coding……
但行好事 莫问前程

Jackson 序列化对象问题

今天再工作中遇到一个问题,将一个对象序列化为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(“”) 注解,自定义序列化结果

赞(0) 打赏
Zhuoli's Blog » Jackson 序列化对象问题
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址