今天再工作中遇到一个问题,将一个对象序列化为json,传给前端做展示。对象成员变量定义按照驼峰形势定义,但是序列化出来的json各个字段却变成了下划线形势(scenesType -> scenes_type),查了好久终于定位到问题所在。
public class InterventionController {
@Autowired
private ObjectMapper objectMapper;
public JsonNode getPageInterventionsDynamic(@RequestParam(value = "limit") Integer limit,
@RequestParam(value = "offset") Integer offset,
@RequestParam(value = "goods_id") Integer goodsId,
@RequestParam(value = "cat_id") Integer catId,
@RequestParam(value = "query") String query,
@RequestParam(value = "rule_type") Integer ruleType) {
ObjectNode node = objectMapper.createObjectNode();
try {
Page<InterventionRule> interventionRulePage =
interventionControllerService.getDinamicPage(limit, offset, goodsId, catId, query, ruleType);
List<InterventionRule> listInterventionRule = interventionRulePage.getContent();
Long total = interventionRulePage.getTotalElements();
ArrayNode arr = objectMapper.createArrayNode();
for (InterventionRule tmpInterventionRule : listInterventionRule) {
/*通过objectMapper.writeValueAsString序列化对象为json对象*/
JsonNode interventionInfo =
objectMapper.readTree(objectMapper.writeValueAsString(tmpInterventionRule));
arr.add(interventionInfo);
}
node.putPOJO("rows", arr);
node.putPOJO("total", total);
return node;
} catch (Exception e) {
logger.error("[InterventionController] :" + e);
node.putPOJO("rows", objectMapper.createArrayNode());
node.putPOJO("total", 0);
return node;
}
}
}
但是序列化的结果却由驼峰转化为小写 + 下划线的形势。通过查找资料定位到应该是ObjectMapper这个Bean定义时有相应的设置,将驼峰转化为小写字母加下划线。最终查到ObjectMapper这个Bean定义的位置在WebMvcConfigurationSupport这个类中,是spring boot启动是加载的。定义如下:
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setWriteAcceptCharset(false);
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(stringConverter);
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new SourceHttpMessageConverter<Source>());
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
messageConverters.add(new AtomFeedHttpMessageConverter());
messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jackson2XmlPresent) {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build();
messageConverters.add(new MappingJackson2XmlHttpMessageConverter(objectMapper));
}
else if (jaxb2Present) {
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build();
messageConverters.add(new MappingJackson2HttpMessageConverter(objectMapper));
}
else if (gsonPresent) {
messageConverters.add(new GsonHttpMessageConverter());
}
}
说明Jackson2ObjectMapperBuilder是影响ObjectMapper的定义的,接下来在项目代码中看到Jackson2ObjectMapperBuilder的定义:
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
builder.featuresToEnable(DeserializationFeature.USE_LONG_FOR_INTS);
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
return builder;
}
Jackson2ObjectMapperBuilder设置了propertyNamingStrategy属性,将驼峰转化为小写字母 + 下划线的形势,去掉该属性,问题得以解决。
引申: 如果想自定义序列化的Json对象的key,可以在对象的成员变量上添加@JsonProperty(“”) 注解,自定义序列化结果