首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring MVC 返回 JSON 去除根節點包裹:一行配置解決 @ResponseBody 序列化多層嵌套

     編輯:Java 相關知識

問題現象

Controller 方法返回對象,配置 MappingJackson2JsonView 後,JSON 輸出被包裹一層鍵名(通常是模型屬性名或類名簡寫):

// 期望
{"code":200,"data":{"id":1}}

// 實際
{"commonAjaxResponse":{"code":200,"data":{"id":1}}}

根因

Spring MVC 的 ModelAndView 模型是 Map 結構,MappingJackson2JsonView 默認將整個模型 Map 序列化。當模型中只有一個條目時,若開啟 extractValueFromSingleKeyModel,會直接序列化該值而非整個 Map。

解決方案:XML 配置開啟提取

<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
    <property name="extractValueFromSingleKeyModel" value="true"/>
</bean>

完整配置上下文

<!-- 内容協商視圖解析器 -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1"/>
    <property name="contentNegotiationManager">
        <bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
            <property name="favorPathExtension" value="true"/>
            <property name="favorParameter" value="false"/>
            <property name="defaultContentType" value="application/json"/>
        </bean>
    </property>
    <property name="defaultViews">
        <list>
            <!-- 關鍵:開啟單鍵模型值提取 -->
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                <property name="extractValueFromSingleKeyModel" value="true"/>
                <!-- 可選:禁用 FAIL_ON_EMPTY_BEANS 避免無屬性類報錯 -->
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="serializationInclusion" value="NON_NULL"/>
                    </bean>
                </property>
            </bean>
        </list>
    </property>
</bean>

Java Config 寫法(Spring 4+ / Spring Boot)

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true).defaultContentType(MediaType.APPLICATION_JSON);
    }

    @Bean
    public View jsonView() {
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setExtractValueFromSingleKeyModel(true); // 核心
        view.setObjectMapper(objectMapper()); // 可選自定義 ObjectMapper
        return view;
    }

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper om = new ObjectMapper();
        om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        return om;
    }
}

Spring Boot 2.x/3.x 自動配置場景

Spring Boot 默認使用 HttpMessageConverter(MappingJackson2HttpMessageConverter)而非 MappingJackson2JsonView,**不會產生根節點包裹問題**。若遷移老項目發現該問題,說明仍在使用 ViewResolver 鏈,按上述 XML/Java Config 修正即可。

對比總結

方案適用場景是否需額外依賴
extractValueFromSingleKeyModel=true傳統 XML/ViewResolver 架構無
改用 @RestController + HttpMessageConverter現代 Spring Boot 項目無
手動返回 ResponseEntity<T>需精確控制狀態碼、Header無

避坑提醒

  1. 模型中**多於一個屬性**時,該屬性不生效,仍序列化整個 Map。
  2. 若 Controller 返回 String 視圖名而非對象,不走此 View,無效。
  3. Jackson 2.12+ 默認啟用 FAIL_ON_EMPTY_BEANS,空 Bean 會拋異常,建議配置 objectMapper.configure(FAIL_ON_EMPTY_BEANS, false)。

一行 extractValueFromSingleKeyModel=true 即可徹底解決老項目 JSON 多層包裝痛點,建議在統一視圖配置類中集中管理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved