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

Spring MVC 處理 JSON 資料與中文亂碼解決方案

     編輯:Java 相關知識

Spring MVC 回傳 JSON 核心機制

Spring MVC 透過 @ResponseBody 配合 HttpMessageConverter 將回傳物件自動序列化為 JSON。預設使用 Jackson (MappingJackson2HttpMessageConverter)。

基本用法

@RestController // 等同 @Controller + 所有方法隱含 @ResponseBody
@RequestMapping("/api/json")
public class JsonController {

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id); // 自動序列化為 JSON
    }

    @PostMapping("/user")
    public User createUser(@RequestBody User user) { // 自動反序列化請求體
        return userService.save(user);
    }
}

中文亂碼根因與解決

原因

Jackson 預設使用 ISO-8859-1 編碼輸出,導致中文字元變亂碼。

方案一:配置 StringHttpMessageConverter (Spring 3.x 風格)

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list><value>text/plain;charset=UTF-8</value></list>
            </property>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="supportedMediaTypes">
                <list><value>application/json;charset=UTF-8</value></list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

方案二:WebMvcConfigurer 程式化配置 (Spring 4+/Boot 推薦)

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?> converters) {
        // 1. JSON 轉換器 (Jackson 2.x)
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        jsonConverter.setSupportedMediaTypes(Arrays.asList(
            MediaType.APPLICATION_JSON_UTF8,
            new MediaType("application", "json", StandardCharsets.UTF_8)
        ));
        // 自訂 ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        jsonConverter.setObjectMapper(mapper);
        converters.add(jsonConverter);

        // 2. String 轉換器 (處理純文字回應)
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        stringConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN));
        converters.add(stringConverter);
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?> converters) {
        // 確保 UTF-8 排在最前
        converters.stream()
            .filter(c -> c instanceof StringHttpMessageConverter)
            .findFirst()
            .ifPresent(c -> ((StringHttpMessageConverter) c).setDefaultCharset(StandardCharsets.UTF_8));
    }
}

方案三:application.properties (Spring Boot)

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.mvc.converters.preferred-json-mapper=jackson
# Jackson 日期格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=false

日期格式化進階

全域配置 (推薦)

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    return mapper;
}

// 注入到 MappingJackson2HttpMessageConverter
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(objectMapper);
    return converter;
}

欄位級別註解

public class Order {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate shipDate; // Java 8 時間 API 直接支援
}

常見問題排查

現象可能原因解決
中文亂碼Converter 編碼未設 UTF-8配置 supportedMediaTypes 含 charset=UTF-8
日期變時間戳Jackson 預設 WRITE_DATES_AS_TIMESTAMPS=true設為 false 並指定 date-format
@ResponseBody 406Accept 標頭不匹配 / 缺 Jackson 依賴引入 jackson-databind、檢查 produces 設定
大量資料 OOM一次序列化大 List分頁、串流輸出 (ResponseBodyEmitter)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved