springboot扩展消息转换器

springboot扩展消息转换器

扩展消息转换器听起来可能有点抽象,实际上消息转换器所起到的作用就是将数据进行序列化和反序列化,例如前端请求传递过来的json数据,我们会反序列化为java对象,同样,给前端返回数据也用到了序列化的,在这些操作中,都会使用消息转换器进行处理。

  • 序列化(Serialization):将Java对象转换为可以传输的格式(如JSON、XML等),以便将数据返回给客户端。这通常发生在Controller方法的返回值被处理时。

  • 反序列化(Deserialization):将传输过来的数据(如JSON、XML等)转换为Java对象,以便在Controller方法中使用。这通常发生在Controller方法的参数被处理时。

    一、Spring Boot 扩展消息转换器的执行流程

    1. HTTP 请求到达

      当一个 HTTP 请求到达 Spring Boot 应用时,DispatcherServlet(分发器 Servlet)会接收到这个请求。

    2. 分发请求

      DispatcherServlet 会将这个请求分发给合适的 HandlerAdapter(处理器适配器)进行处理。

    3. 查找处理器

      HandlerAdapter 会找到处理这个请求的 Controller,并调用相应的处理方法。

    4. 数据转换

      在调用处理方法时,如果方法的参数或返回值需要进行数据转换(例如,参数是一个 Java 对象,但客户端发送的是一个 JSON 格式的请求),HandlerAdapter 会使用 HttpMessageConverter (消息转换器) 来进行数据转换。

    5. 选择合适的消息转换器

      HandlerAdapter 会遍历所有已注册的 HttpMessageConverter,找到一个支持转换当前数据的 HttpMessageConverter,然后使用这个 HttpMessageConverter 来进行数据转换。

    6. 调用处理方法

      数据转换完成后,处理方法会被执行,处理结果会被返回给 HandlerAdapter

    7. 响应数据转换

      HandlerAdapter 会再次使用 HttpMessageConverter 来将处理结果转换为 HTTP 响应。

    8. 返回响应

      最后,DispatcherServlet 会将 HTTP 响应返回给客户端。

    通过上述流程,我们可以知道,在外面添加自定义的消息转换器时,需要添加序列化和反序列化两种方式,以便处理接收数据和返回数据

具体例子:

@RestController
public class MyController {

    @PostMapping("/example")
    public Result example(@RequestBody MyObject myObject) {
        // 处理myObject
        return Result.success();
    }
}

  • 请求到达:客户端发送一个包含JSON数据的HTTP POST请求到/example端点。

  • 数据转换:Spring Boot会使用合适的HttpMessageConverter(如MappingJackson2HttpMessageConverter)将请求体中的JSON数据反序列化为 MyObject类型的Java对象。

  • 调用处理方法:反序列化后的MyObject对象作为参数传递给example方法。

通过上述我们也就可以知道,平时我们使用的@RequestBody实际上就是使用消息转换器起到反序列化的作用,同样的,RestController就是使用消息转换器起到反序列化的作用

二、自定义消息消息转换器

这里我们以时间格式处理为例,在前后端数据传递过程中,时间格式处理是经常会遇到的

  • 配置类设置
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 设置对象转换器,可以将java对象转换为json字符串
        converter.setObjectMapper(new JacksonObjectMapper());

        // 将自定义的转换器添加到spring MVC框架的消息转换器列表中,并且放在第一个位置
        converters.add(0, converter);
    }
}

  • JacksonObjectMapper设置
package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        // addDeserializer方法用于添加反序列化器,用于前端传递的时间字符串转为LocalDateTime对象
        // addSerializer方法用于添加序列化器,用于将LocalDateTime对象转为前端需要的时间字符串
        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 自定义类型转换器(Type Converter)允许你在不修改默认映射规则的情况下,扩展或定制框架对特定数据类型之间的转换过程。这对于处理一些特殊的业务逻辑或第三方库的数据格式转换非常有用。以下是自定义类型转换器的基本步骤: 1. 创建类型转换器接口:实现`org.springframework.core.convert.converter.Converter`接口,这个接口有一个`convert`方法,用于执行转换。 ```java public class CustomConverter implements Converter<String, MyCustomType> { // ... @Override public MyCustomType convert(String source) { // 在这里实现将字符串转换为MyCustomType的具体逻辑 return ...; } // ... } ``` 2. 注册转换器:在Spring Boot应用的配置类中使用`@Bean`和`@Configuration`注解来注册你的转换器,并告诉Spring它是如何找到和使用的。 ```java @Configuration public class ConversionConfig { @Bean public Converter<String, MyCustomType> customConverter() { return new CustomConverter(); } @Bean public TypeConverterRegistry typeConverterRegistry(ApplicationContext context) { TypeConverterRegistry registry = new TypeConverterRegistry(context); registry.addConverter(customConverter()); return registry; } } ``` 3. 使用自定义转换器:在需要进行类型转换的地方,Spring会自动调用已注册的转换器。例如,可以在`@RequestMapping`方法的参数上使用`@RequestBody`或`@ModelAttribute`注解来触发转换。 ```java @PostMapping("/my-endpoint") public ResponseEntity<?> handleRequest(@RequestBody String input) { MyCustomType myObject = typeConverter.convert(input); // Spring会自动调用注册的转换器 // ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值