2011-01-27 33 views
39

想象我有這樣的註釋方法在春季3 @Controller春@ResponseBody配置JSON格式

@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); 

有沒有什麼辦法可以配置這種行爲?

我發現了幾個相關的問題,但我不知道如何使其適應我的具體情況:

  1. spring prefixjson with responsebody
  2. Who sets response content-type in Spring MVC (@ResponseBody)

謝謝!

回答

15

AngerClown pointed me朝着正確的方向前進。

這是我最終做的,以防萬一任何人發現它有用。

<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> 

我仍然要弄清楚如何將其他屬性配置,如:

om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true); 
+0

這對我不起作用。得到這個 「org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping:86-AbstractDetectingUrlHandlerMapping.java {HTTP線程池4848-(2)} |拒絕bean的名字 'jacksonObjectMapper':沒有URL路徑標識」 – Bobo 2011-05-19 14:15:23

+2

剛一個不會用`不能用`我發現了困難的方式。 – 2012-10-09 19:18:14

+0

@ JD.Thanks很多! – 2013-11-26 19:02:54

2

您可以在Spring xml文件中將ObjectMapper配置爲一個bean。對ObjectMapper的引用是​​類。然後您需要將視圖附加到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文件中其他位置定義。請注意,您可以使用Enums Jackson定義的直接設置Spring屬性值;請參閱this question

此外,ContentNegotiatingViewResolver可能不是必需的,它只是我在現有項目中使用的代碼。

+1

謝謝你,你的回答對我幫助很大。看到我的答案與最終和工作配置。 – 2011-01-28 17:46:20

1

是的,但如果你開始使用例如混入發生,你不能是具有ObjectMapper作爲一個單身,因爲您將全局應用配置。所以你會在同一個ObjectMapper實例上添加或設置mixin類?

+0

好問題。我不知道我採取的方法是否可行。 – 2011-02-10 16:33:30

4

我寫我自己的FactoryBean其實例化一個ObjectMapper(簡體版):

public class ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>{ 

     @Override 
     public ObjectMapper getObject() throws Exception { 
       ObjectMapper mapper = new ObjectMapper(); 
       mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 
       return mapper; 
     } 

     @Override 
     public Class<?> getObjectType() { 
       return ObjectMapper.class; 
     } 

     @Override 
     public boolean isSingleton() { 
       return true; 
     } 

} 

在春天配置用法:

<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> 

27

我needeed解決非常類似的問題,wh ich正在配置Jackson Mapper「爲了基督的緣故,不要爲空值序列化!!!」。

我不想留下mvc:annotation-driven標籤,所以我發現,如何在不刪除mvc:註解驅動的情況下配置Jackson的ObjectMapper並添加不是很花哨的ContentNegotiatingViewResolver。

美麗的是你不必自己編寫任何Java代碼!

這裏是XML配置(不要與Jackson類的不同名稱空間混淆,我只是使用新的Jakson 2.x庫...同樣應該也可以與Jackson 1.x庫一起使用):

<mvc:annotation-driven> 
    <mvc:message-converters register-defaults="true"> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper"> 
       <bean class="com.fasterxml.jackson.databind.ObjectMapper"> 
        <property name="serializationInclusion"> 
         <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value> 
        </property> 
       </bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 
10

在spring3.2,新的解決方案是通過介紹:http://static.springsource.org/spring/docs/3.2.0.BUILD-SNAPSHOT/api/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.html, 下面是我的例子:

<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> 
1

你可以做以下(傑克遜版< 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); 
    } 
} 

Spring配置:

<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> 
31

對於誰使用基於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); 
    } 

.... 

} 

我使用MappingJackson2HttpMessageConverter - 來自fasterxml。

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.3.1</version> 
</dependency> 

如果你想使用Codehaus的傑克遜映射器,而不是使用一個MappingJacksonHttpMessageConverter

<dependency> 
    <groupId>org.codehaus.jackson</groupId> 
    <artifactId>jackson-mapper-asl</artifactId> 
    <version>${codehaus.jackson.version}</version> 
</dependency> 
4

不回答這個問題,但是這是頂級谷歌的結果。

如果有人來到這裏,想要做呢春4(因爲它發生在我身上),你可以在返回類使用註釋

@JsonInclude(Include.NON_NULL) 

10

For Spring version 4.1。3+

我試圖賈馬的解決方案,但後來所有的反應都與內容類型「應用/ JSON的」返回,包括主,生成的HTML頁面。

覆蓋configureMessageConverters(...)防止彈簧設置默認轉換器。春天4.1.3允許已配置的轉換器的修改通過重寫extendMessageConverters(...)

@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); 
    } 
} 

看到org.springframework..WebMvcConfigurationSupport#getMessageConverters()

看到org.springframework..WebMvcConfigurationSupport#addDefaultHttpMessageConverters(...)