Spring MVC中如何排除指定Java实体不受全局ObjectMapper配置影响
嘿,针对你在Spring MVC里想要排除某个DTO不受全局ObjectMapper的PascalCase命名策略影响的需求,我给你整理了几个实用的解决方案,都是项目里常用的思路:
方案1:用@JsonNaming注解直接覆盖全局配置
这是最简单直接的方法,只需要在你想要排除的DTO类上添加Jackson的@JsonNaming注解,指定你想要的命名策略(比如默认的小驼峰),这样这个类就会忽略全局的PascalCase配置,用自己的策略序列化/反序列化。
举个例子:
import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; @JsonNaming(PropertyNamingStrategy.LowerCamelCaseStrategy.class) public class YourExcludedDTO { private String userName; private Integer userAge; // getter、setter省略 }
这个注解是类级别的,只会作用于当前DTO,不会影响其他实体类,非常省心。
方案2:自定义条件化的命名策略
如果你的需求更复杂(比如要排除多个类,或者需要动态判断),可以自定义一个继承自PascalCaseStrategy的命名策略,在里面添加判断逻辑,遇到目标类就使用默认的命名规则。
代码示例:
import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.AnnotatedField; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; public class ConditionalPascalCaseStrategy extends PropertyNamingStrategy.PascalCaseStrategy { private final Class<?> excludedClass; public ConditionalPascalCaseStrategy(Class<?> excludedClass) { this.excludedClass = excludedClass; } @Override public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) { // 判断当前字段所属的类是否是要排除的类 if (excludedClass.equals(field.getDeclaringClass())) { return PropertyNamingStrategy.LOWER_CAMEL_CASE.nameForField(config, field, defaultName); } return super.nameForField(config, field, defaultName); } @Override public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if (excludedClass.equals(method.getDeclaringClass())) { return PropertyNamingStrategy.LOWER_CAMEL_CASE.nameForGetterMethod(config, method, defaultName); } return super.nameForGetterMethod(config, method, defaultName); } @Override public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if (excludedClass.equals(method.getDeclaringClass())) { return PropertyNamingStrategy.LOWER_CAMEL_CASE.nameForSetterMethod(config, method, defaultName); } return super.nameForSetterMethod(config, method, defaultName); } }
然后修改你的Spring配置,使用这个自定义策略:
<property name="objectMapper"> <bean class="com.fasterxml.jackson.databind.ObjectMapper"> <property name="propertyNamingStrategy"> <bean class="com.yourpackage.ConditionalPascalCaseStrategy"> <constructor-arg value="com.yourpackage.YourExcludedDTO"/> </bean> </property> </bean> </property>
这种方式适合需要批量排除或者有复杂判断逻辑的场景。
方案3:为排除的DTO单独配置ObjectMapper
如果这个DTO需要完全独立的序列化配置(不止是命名策略),可以单独创建一个不带PascalCase配置的ObjectMapper,然后在Controller里手动使用它来处理这个DTO。
首先在Spring配置里定义这个专属的ObjectMapper:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Qualifier; @Bean @Qualifier("defaultObjectMapper") public ObjectMapper defaultObjectMapper() { // 创建默认的ObjectMapper,不设置PascalCase策略 return new ObjectMapper(); }
然后在Controller里注入这个ObjectMapper,手动序列化:
import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class YourController { @Autowired @Qualifier("defaultObjectMapper") private ObjectMapper defaultMapper; @GetMapping("/excluded-dto") public ResponseEntity<String> getExcludedDTO() throws JsonProcessingException { YourExcludedDTO dto = new YourExcludedDTO(); dto.setUserName("testUser"); dto.setUserAge(25); // 使用专属的ObjectMapper序列化 String json = defaultMapper.writeValueAsString(dto); return ResponseEntity.ok(json); } }
这种方式灵活性最高,但需要手动处理序列化,适合特殊场景。
内容的提问来源于stack exchange,提问作者itjustfortech 2018
相关产品推荐
相关产品推荐

