今天使用分页时,发现前端页面,无法正确显示页号,经过debug发现,是传送回前端的Long类型的总记录数被全局的消息转换器转换成了 String 类型,导致出现了bug,本来将 Long 转成String是为了防止前端精度丢失问题,但是分页查询传回前端的 totalRows 总记录数并没有必要进行转换的必要,如何忽略是个问题。
定义的消息转换器 @Bean :
/*** 统一定义Long序列化转String设置(所有的Long序列化成String)* @return*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){//构建http信息转换对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = new ObjectMapper();//反序列化忽略未知属性,不会抛出异常objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);SimpleModule simpleModule = new SimpleModule();//Long | long 序列化StringsimpleModule.addSerializer(Long.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);//注册转化器objectMapper.registerModule(simpleModule);//设置序列化实现converter.setObjectMapper(objectMapper);return converter;
}
该函数的功能是创建并配置一个MappingJackson2HttpMessageConverter对象,用于将Java对象转换为HTTP消息体。主要配置包括:
- 创建MappingJackson2HttpMessageConverter实例。
- 创建ObjectMapper实例并配置反序列化时忽略未知属性。
- 创建SimpleModule实例,并注册Long类型和long类型的序列化转换器,使其在序列化时转换为String类型。
- 将上述ObjectMapper实例注册到MappingJackson2HttpMessageConverter中。
- 返回配置好的MappingJackson2HttpMessageConverter实例。
第一个想法:
通过创建自定义的混合类(Mix-in)来实现对特定字段的序列化控制。
// 创建一个mix-in类
abstract class MyClassMixIn {@JsonSerialize(using = LongSerializer.class)public abstract long getMyLong();
}// 然后在 ObjectMapper 配置中注册 mix-in 类
objectMapper.addMixIn(PageResult.class, MyClassMixIn.class);
请注意,这里假设存在一个默认处理Long类型的 LongSerializer,实际上Jackson并没有这样的内置序列化器,上述示例仅用于说明如何局部覆盖全局配置。实际应用中可能需要你自己定义一个序列化器或选择其他适当的方式。
第二个想法
让其不会被全局配置影响,将使用默认的Long序列化方式(失败,前端报错500,后端控制台没输出报错)
@ApiModel(description = "分页工具类")
@Data
public class PageResult<T> implements Serializable {/*** 总记录数*/@ApiModelProperty(value = "总记录数", position = 1)@JsonSerialize(using = JsonSerializer.None.class)private Long totalRows;
}
想法3:
字段忽略序列化(失败,传回前段的响应体中,totalRows字段直接消失了)
/*** 分页工具类*/
@ApiModel(description = "分页工具类")
@Data
@JsonIgnoreProperties({"totalRows"})
public class PageResult<T> implements Serializable {/*** 总记录数*/@ApiModelProperty(value = "总记录数", position = 1)private Long totalRows;
}
第四种方法,自定义序列化方式(成功)前端成功收到Long类型的数据
public class DefaultLongSerializer extends JsonSerializer<Long> {@Overridepublic void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeNumber(value);}
}
// 在你的类中使用自定义序列化器
@ApiModel(description = "分页工具类")
@Data
public class PageResult<T> implements Serializable {/*** 总记录数*/@ApiModelProperty(value = "总记录数", position = 1)// 这个字段将按照默认方式序列化Long@JsonSerialize(using = DefaultLongSerializer.class)private Long totalRows;
}
如果全局设置已经将所有Long转为String,而你只想让某个字段保持原样,那么可能需要在序列化该特定对象时临时更改或覆盖ObjectMapper的配置,或者在处理该特定字段时采用其他方法,而不是直接通过注解的方式。这通常会涉及到更复杂的逻辑和代码组织结构。