springBoot的序列化与反序列化

本文深入探讨SpringBoot中序列化与反序列化的复杂过程,包括HTTP请求响应信息转换、jackson版本选择、RequestBody与ResponseBody处理、信息转换器配置及Http请求处理器工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot中的序列化与反序列化有一个相对比较复杂的转换过程,它主要是HTTP请求、响应的信息类型转换,包含编码、信息类型、信息转换器、注解方法的处理适配器、请求接收的信息处理器等等。我们就先从大家常用的RequestBody和ResponseBody说起。


一、引入jackson:

小D在练习搭建springMvc框架时,遇到一个Controller接收实体参数问题:method为post,content-type为application/json; charset=utf-8的http请求,Controller接收
是@RequestBody ,但无法序列化为Object类型,其它类型却可以,并且报415错误Unsupported Media Type,可以排除注解未开启、请求内容类型不一致问题,那么最有可能是jackson包没引用或者与spring版本号不一致。Spring5.x引用jackson 2.9版本,Spring4.x引用jackson 2.6,Spring3.x引用jackson 1.9版本都是可以的。


二、RequestBody 中到的处理适配器:

老L目前公司用的框架为springboot-1.0,对应的jackson为2.8。打开@RequestBody,里有个很重要的提示@see …

* @author Arjen Poutsma
 * @since 3.0
 * @see RequestHeader
 * @see ResponseBody
 * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
 * @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {

这个版本里,RequestMappingHandlerAdapter代替了
AnnotationMethodHandlerAdapter,它主要是处理请求和响应,在项目启动时会执行它的构造函数,初始化默认的HttpMessageConverter(核心的转换器),再执行WebMvcConfiguraionSupport类里的createRequestMappingHandlerAdapter去创建请求的处理器,并去执行下面的注入方法

@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
adapter.setContentNegotiationManager(mvcContentNegotiationManager());
adapter.setMessageConverters(getMessageConverters());
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
adapter.setCustomArgumentResolvers(getArgumentResolvers());

其中getMessageConverters里的configureMessageConverters为添加转换器。


三、添加信息转换器的几种方式:

1. 注解Bean形式

// 这样做springboot会把我们自定义的converter放在顺序上的最高优先级(List的头部)
// 即有多个converter都满足Accpet/ContentType/MediaType的规则时,优先使用我们这个
@Bean
public MappingJackson2HttpMessageConverter  mappingJackson2HttpMessageConverter(){
		return new MappingJackson2HttpMessageConverter();
}

2. springboot通过继承WebMvcConfigurerAdapter,重写configureMessageConverters。
(Spring3.x 用MappingJacksonHttpMessageConverter
Spring4.x 用MappingJackson2HttpMessageConverter)

// 通常在只有一个自定义WebMvcConfigurerAdapter时,会把这个方法里面添加的converter(s)依次放在最高优先级(List的头部)
// 虽然第一种方式的代码先执行,但是bean的添加比这种方式晚,所以方式二的优先级 大于 方式一
@Configuration
@EnableWebMvc
public class WebMvcConfigure extends WebMvcConfigurerAdapter {

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
		MappingJackson2HttpMessageConverter mjhmc=new MappingJackson2HttpMessageConverter(objectMapper());
		converters.add(mjhmc);
	}

	@Bean
	public ObjectMapper objectMapper(){
		ObjectMapper om= Jackson2ObjectMapperBuilder.json().build();
		om.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
		om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
		simpleModule.addSerializer(Long.TYPE,ToStringSerializer.instance);
		simpleModule.addSerializer(SwordsAbstractModel.class,new CustomerJpaModelSerializer());
		om.registerModule(simpleModule);
		return om;
	}
}

并且针对项目对ObjectMapper自定义配置,反序列化时禁止对忽略的属性和未知的属性报错,以及对没有匹配的属性名称时不作失败处理(MapperFeature.AUTO_DETECT_FIELDS) 等等。
SimpleModule则在序列化和反序列化的情况下,才会使用其规则。截图中是在序列化时将Long类型转化为String类型。而下面这种写法可以用注解来代替

simpleModule.addSerializer(SwordsAbstractModel.class,new CustomerJpaModelSerializer());
@JsonSerialize(
    using = CustomerJpaModelSerializer.class
)
public abstract class SwordsAbstractModel implements Serializable {
 

还有许多Json的注解可以简便配置,给大家提供个链接
https://blog.youkuaiyun.com/tanga842428/article/details/79201937

3. extendMessageConverters方式:

// 添加converter的第三种方式
// 同一个WebMvcConfigurerAdapter中的configureMessageConverters方法先于extendMessageConverters方法执行
// 可以理解为是三种方式中最后执行的一种,不过这里可以通过add指定顺序来调整优先级,也可以使用remove/clear来删除converter,功能强大
// 使用converters.add(xxx)会放在最低优先级(List的尾部)
// 使用converters.add(0,xxx)会放在最高优先级(List的头部)
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
		converters.add(new MappingJackson2HttpMessageConverter());
}

以上简单讲述了项目运行时jackson解析原理。


四、Http请求处理器:

具体Http请求是通过RequestResponseBodyMethodProcessor类去处理的,接收请求是通过readWithMessageConverters方法,其核心还是通过之前配置的HttpMessageConverter进行数据转换为对象。如果返回请求为**@ResponseBody**,则会调用该类里handleReturnValue方法,将对象转换为相应的信息。


欢迎大家可以关注我,联系我进行技术讨论。

### Spring Boot中序列化反序列化的功能及作用 在Spring Boot中,序列化(Serialization)和反序列化(Deserialization)是数据转换的核心机制。序列化是指将对象的状态信息转换为可以存储或传输的形式,而反序列化则是指将这些形式的数据重新转换为对象的过程。 #### 1. 序列化的作用 序列化的主要作用是将Java对象转换为字节流,以便能够将其保存到文件、数据库或者通过网络进行传输。这种机制确保了对象可以在不同的环境中被正确地恢复和使用[^2]。例如,在分布式系统中,当需要将对象从一个服务传递到另一个服务时,必须先将对象序列化为字节流。 #### 2. 反序列化的作用 反序列化的作用序列化相反,它是将字节流重新转换为Java对象的过程。这一过程对于恢复对象状态至关重要,尤其是在跨进程通信或持久化存储的场景下。例如,当从文件或网络接收到序列化的数据时,反序列化可以将其还原为原始的对象结构[^2]。 #### 3. 自定义序列化反序列化 在某些情况下,标准的序列化反序列化可能无法满足特定需求。例如,某些字段可能需要特殊的处理逻辑,或者需要对JSON格式进行自定义映射。在这种情况下,可以通过实现`JsonSerializer`和`JsonDeserializer`类,并结合`@JsonComponent`注解来定义自定义的序列化反序列化逻辑[^3]。这种方式允许开发者灵活地控制数据的转换过程。 #### 4. 默认的序列化反序列化工具:Jackson Spring Boot默认使用Jackson库来处理JSON格式的序列化反序列化操作。Jackson通过其模块化设计,允许开发者通过`Module`接口注册自定义的序列化器和反序列化器[^1]。此外,Jackson还提供了丰富的注解支持,例如`@JsonProperty`、`@JsonIgnore`等,用于简化序列化反序列化的配置。 #### 5. `serialVersionUID`的作用 在Java的序列化机制中,`serialVersionUID`是一个非常重要的概念。它用于标识类的不同版本。如果类中没有显式定义`serialVersionUID`,JVM会根据类的结构自动生成一个值。只要类的结构没有发生实质性变化(如添加或删除字段),即使重新编译多次,生成的`serialVersionUID`也不会发生变化[^2]。这有助于确保在不同版本之间进行反序列化时的一致性。 ```java import java.io.Serializable; public class Example implements Serializable { private static final long serialVersionUID = 1L; private String name; public Example(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` ### 示例代码:自定义序列化反序列化 以下是一个简单的示例,展示如何在Spring Boot中通过`@JsonComponent`实现自定义的序列化反序列化逻辑。 ```java import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.springframework.boot.jackson.JsonComponent; import java.io.IOException; @JsonComponent public class CustomSerializer extends JsonSerializer<Example> { @Override public void serialize(Example value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); gen.writeStringField("customName", value.getName().toUpperCase()); gen.writeEndObject(); } } ``` ```java import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import org.springframework.boot.jackson.JsonComponent; import java.io.IOException; @JsonComponent public class CustomDeserializer extends JsonDeserializer<Example> { @Override public Example deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); String name = node.get("customName").asText().toLowerCase(); return new Example(name); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值