java - تكوين الربيع تنسيقSesponseBody JSON




spring spring-mvc (8)

تخيل لدي هذه الطريقة المشروحة في Spring 3Controller

@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. ربيع prefixjson مع رد
  2. من يحدد نوع محتوى الاستجابة في Spring MVC (ResponseBody)

شكرا !


أنا بحاجة إلى حل مشكلة مشابهة جدا ، والتي هي تكوين مخطط جاكسون إلى "لا تسلسل القيم الفارغة من أجل المسيح!".

لم أكن أرغب في ترك علامة mvc خيارية: علامة مبنية على التعليق التوضيحي ، لذلك وجدت كيفية تكوين ObjectMapper من جاكسون بدون إزالة mvc: تحريك التعليقات وإضافة محتوى غير حقيقي إلى حد كبير ContentNegotiatingViewResolver.

الشيء الجميل هو أنك لا تحتاج إلى كتابة أي رمز جافا بنفسك!

وهنا تكوين XML (لا يتم الخلط بينه وبين مساحات الأسماء المختلفة لفصول جاكسون ، استخدم ببساطة مكتبة 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>

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

لا يجيب على السؤال ولكن هذا هو أعلى نتيجة جوجل.

إذا كان أي شخص يأتي هنا ويريد فعل ذلك في الربيع 4 (كما حدث لي) ، يمكنك استخدام التعليق التوضيحي

@JsonInclude(Include.NON_NULL)

على الطبقة العائدة.


للناس الذين يستخدمون التكوين الربيع القائمة على جافا :

@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-jackson ، استخدم بدلاً من ذلك MappingJacksonHttpMessageConverter

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


يمكنك القيام بما يلي (الإصدار 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>

أشارت AngerClown إلى الاتجاه الصحيح.

هذا ما فعلته في النهاية ، فقط في حال وجد أي شخص أنه مفيد.

<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://.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);

لإصدار الربيع 4.1.3+

لقد جربت حل جاما ، ولكن بعد ذلك تم إرجاع جميع الردود باستخدام Content-type "application / 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(...)





jackson