Java Spring配置@ResponseBody JSON格式

Java Spring配置@ResponseBody JSON格式,java,spring,spring-mvc,jackson,Java,Spring,Spring Mvc,Jackson,假设我在Spring3@控制器中有这个带注释的方法 @RequestMapping("") public @ResponseBody MyObject index(@RequestBody OtherObject obj) { MyObject result = ...; return result; } 但我需要配置输出json格式,就像我在做: ObjectMapper om = new ObjectMapper(); om.configure(JsonGenerator.

假设我在Spring3@控制器中有这个带注释的方法

@RequestMapping("")
public @ResponseBody MyObject index(@RequestBody OtherObject obj) {
    MyObject result = ...;
    return result;
}
但我需要配置输出json格式,就像我在做:

ObjectMapper om = new ObjectMapper();
om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);
om.getSerializationConfig()
        .setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
om.getSerializationConfig()
        .set(SerializationConfig.Feature.INDENT_OUTPUT, false);
有没有办法配置此行为

我发现了几个相关的问题,但我不确定如何使它们适应我的具体情况:


  • 谢谢大家!

    您可以将ObjectMapper配置为SpringXML文件中的bean。保存对ObjectMapper的引用的是
    MappingJacksonJsonView
    类。然后需要将视图附着到ViewResolver

    像这样的方法应该会奏效:

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
          <property name="mediaTypes">
          <map>
            <entry key="json" value="application/json" />
            <entry key="html" value="text/html" />
          </map>
        </property>
        <property name="viewResolvers">
          <list>
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="prefix" value="/WEB-INF/jsp/" />
              <property name="suffix" value=".jsp" />
            </bean>
          </list>
        </property>
        <property name="defaultViews">
          <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
              <property name="prefixJson" value="false" />
              <property name="objectMapper" value="customObjectMapper" />
            </bean>
          </list>
        </property>
      </bean>
    
    
    
    其中
    customObjectMapper
    在xml文件的其他地方定义。请注意,您可以使用Enum Jackson定义直接设置Spring属性值;看

    此外,ContentNegotingViewResolver可能不是必需的,它只是我在现有项目中使用的代码。

    改变了方向

    这就是我最后做的,以防万一有人觉得有用

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                    <property name="objectMapper" ref="jacksonObjectMapper" />
                </bean>
            </list>
        </property>
    </bean>
    
    <!-- jackson configuration : https://stackoverflow.com/questions/3661769 -->
    <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
    <bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
        factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />
    <bean
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="jacksonSerializationConfig" />
        <property name="targetMethod" value="setSerializationInclusion" />
        <property name="arguments">
            <list>
                <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_DEFAULT</value>
            </list>
        </property>
    </bean>
    

    是的,但是如果您开始使用mixin,会发生什么呢?例如,您不能将ObjectMapper作为一个单例,因为您将全局应用配置。因此,您将在同一ObjectMapper实例上添加或设置mixin类?

    看看Rick Hightower的方法。他的方法避免了将ObjectMapper配置为单例,并允许您按照每个请求方法以不同的方式过滤同一对象的JSON响应


    我编写了自己的FactoryBean,它实例化了ObjectMapper(简化版):

    公共类ObjectMapperFactoryBean实现FactoryBean{
    @凌驾
    公共ObjectMapper getObject()引发异常{
    ObjectMapper mapper=新的ObjectMapper();
    mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    返回映射器;
    }
    @凌驾
    公共类getObjectType(){
    返回ObjectMapper.class;
    }
    @凌驾
    公共布尔isSingleton(){
    返回true;
    }
    }
    
    以及spring配置中的用法:

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                    <property name="objectMapper" ref="jacksonObjectMapper" />
                </bean>
            </list>
        </property>
    </bean>
    
    
    

    我需要解决非常类似的问题,那就是将Jackson Mapper配置为“看在上帝的份上,不要序列化空值!!!”

    我不想留下花哨的mvc:annotation-driven标记,所以我找到了如何在不删除mvc:annotation-driven和添加不太花哨的contentnegotingviewresolver的情况下配置Jackson的ObjectMapper

    最美妙的是,您不必自己编写任何Java代码

    这里是XML配置(不要与Jackson类的不同名称空间混淆,我只是使用了新的Jakson 2.x库……同样的配置也适用于Jackson 1.x库):

    
    非空
    
    在spring3.2中,新的解决方案由以下内容引入:, 以下是我的例子:

     <mvc:annotation-driven>
       ​<mvc:message-converters>
         ​​<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           ​​​<property name="objectMapper">
             ​​​​<bean
     class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
               ​​​​​<property name="featuresToEnable">
                 ​​​​​​<array>
                   ​​​​​​​<util:constant static-field="com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES" />
                 ​​​​​​</array>
               ​​​​​</property>
             ​​​​</bean>
           ​​​</property>
         ​​</bean>
       ​</mvc:message-converters>
     </mvc:annotation-driven>
    
    
    ​
    ​​
    ​​​
    ​​​​
    ​​​​​
    ​​​​​​
    ​​​​​​​
    ​​​​​​
    ​​​​​
    ​​​​
    ​​​
    ​​
    ​
    
    您可以执行以下操作(jackson版本<2):

    自定义映射器类:

    import org.codehaus.jackson.JsonGenerator;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.SerializationConfig;
    import org.codehaus.jackson.map.annotate.JsonSerialize;
    
    public class CustomObjectMapper extends ObjectMapper {
        public CustomObjectMapper() {
            super.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);
            super.getSerializationConfig()
                    .setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
            super.getSerializationConfig()
                    .set(SerializationConfig.Feature.INDENT_OUTPUT, false);
        }
    }
    
    弹簧配置:

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                <property name="objectMapper">
                    <bean class="package.CustomObjectMapper"/>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    

    对于使用基于Java的Spring配置的用户:

    @Configuration
    @ComponentScan(basePackages = "com.domain.sample")
    @EnableWebMvc
    public class SpringConfig extends WebMvcConfigurerAdapter {
    ....
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            final ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            converter.setObjectMapper(objectMapper);
            converters.add(converter);
            super.configureMessageConverters(converters);
        }
    
    ....
    
    }
    
    如果要使用codehaus jackson映射器,请使用此映射器
    MappingJacksonHttpMessageConverter

     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${codehaus.jackson.version}</version>
     </dependency>
    
    
    org.codehaus.jackson
    杰克逊地图绘制者
    ${codehaus.jackson.version}
    
    没有回答这个问题,但这是谷歌的最热门搜索结果

    如果有人来这里想为Spring4做这件事(就像我遇到的那样),你可以使用注释

    @JsonInclude(Include.NON_NULL)
    

    返回课堂。

    对于Spring版本4.1.3+

    我尝试了Jama的解决方案,但是所有的响应都返回了“application/json”内容类型,包括主生成的HTML页面

    重写configureMessageConverters(…)会阻止spring设置默认转换器。Spring 4.1.3允许通过重写extendMessageConverters(…)修改已配置的转换器:

    @配置
    公共类转换器配置扩展WebMVCConfigureAdapter{
    @凌驾
    public void extendMessageConverters(列表转换器:转换器){
    if(AbstractJackson2HttpMessageConverter的转换器实例){
    AbstractJackson2HttpMessageConverter c=(AbstractJackson2HttpMessageConverter)转换器;
    ObjectMapper ObjectMapper=c.getObjectMapper();
    objectMapper.setSerializationInclusion(Include.NON_NULL);
    }
    }
    超级扩展消息转换器(转换器);
    }
    }
    
    请参阅
    org.springframework..WebMVC配置支持#getMessageConverters()

    请参阅
    org.springframework..WebMvcConfigurationSupport#addDefaultHttpMessageConverters(…)


    谢谢你,你的回答对我帮助很大。请看我的最终和工作配置的答案。好问题。我不知道我所采取的方法是否可行。这对我不起作用。得到这个“org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping:86 AbstractDetectingUrlHandlerMapp
    @Configuration
    @ComponentScan(basePackages = "com.domain.sample")
    @EnableWebMvc
    public class SpringConfig extends WebMvcConfigurerAdapter {
    ....
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            final ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            converter.setObjectMapper(objectMapper);
            converters.add(converter);
            super.configureMessageConverters(converters);
        }
    
    ....
    
    }
    
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.3.1</version>
    </dependency>
    
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${codehaus.jackson.version}</version>
     </dependency>
    
    @JsonInclude(Include.NON_NULL)
    
    @Configuration
    public class ConverterConfig extends WebMvcConfigurerAdapter {
        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            for (HttpMessageConverter<?> converter : converters) {
                if (converter instanceof AbstractJackson2HttpMessageConverter) {
                    AbstractJackson2HttpMessageConverter c = (AbstractJackson2HttpMessageConverter) converter;
                    ObjectMapper objectMapper = c.getObjectMapper();
                    objectMapper.setSerializationInclusion(Include.NON_NULL);
                }
            }
    
            super.extendMessageConverters(converters);
        }
    }