spring boot · 2024-08-31 0

springboot 自定义 HttpMessageConverter

一、自定义 HttpMessageConverter

HttpMessageConverter 报文信息转化器,将请求报文转化成 Java 对象,或将 Java 对象转化为响应报文

HttpMessageConverter 提供了两个注解和两个类型:@RequestBody,@ResponseBody,RequestEntity,ResponseEntity

1.pom 依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
        <optional>true</optional>
    </dependency>
</dependencies>

2.java

@Setter
@Getter
public class Pet {

    private String name;

    private Integer age;
}
public class MyMessageConverter implements HttpMessageConverter<Pet> {

    public final static String APPLICATION_MY_DATA = "application/my-data";

    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Pet.class);
    }

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Pet.class);
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes(APPLICATION_MY_DATA);
    }

    @Override
    public Pet read(Class<? extends Pet> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        // 请求体,形如:name:pet1, age:1
        String body = StreamUtils.copyToString(inputMessage.getBody(), Charset.defaultCharset());
        Map<String, String> map = Arrays.stream(body.split(","))
                .map(item -> item.split(":"))
                .collect(Collectors.toMap(pair -> pair[0].trim(), pair -> pair[1].trim()));

        Pet pet = new Pet();
        pet.setName(map.get("name"));
        pet.setAge(Integer.valueOf(map.get("age")));
        return pet;
    }

    @Override
    public void write(Pet pet, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        OutputStream body = outputMessage.getBody();
        String str = String.format("pet name: %s, pet age: %s", pet.getName(), pet.getAge());
        body.write(str.getBytes());
    }
}
@Configuration(proxyBeanMethods = false)
public class MyConfig {

    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new MyMessageConverter());
            }
        };
    }
}
@RestController
public class IndexController {

    @PostMapping(value = "/pet1", produces = {MyMessageConverter.APPLICATION_MY_DATA})
    public Pet pet1(@RequestBody Pet request) {
        Pet res = new Pet();
        res.setName(request.getName());
        res.setAge(request.getAge());
        return res;
    }
}
@SpringBootApplication
public class WebBoot {

    public static void main(String[] args) {
        SpringApplication.run(WebBoot.class, args);
    }
}

3.测试

zxm@zxm-pc:~$ curl -X POST -H "Content-Type: application/my-data" -d 'name:pet11, age:11' http://localhost:8080/pet1
pet name: pet11, pet age: 11