Spring Rest无法返回字符串列表JSON响应的问题咨询
问题解决与答疑
一、报错原因及解决方案
你遇到的HttpMessageNotWritableException本质是Spring找不到合适的JSON转换器来序列化Arrays$ArrayList(Arrays.asList()返回的内部列表实现),尽管手动添加了Jackson依赖,可能存在以下问题及对应解决方法:
1. 检查Jackson依赖完整性
确保WEB-INF/lib下包含以下3个核心Jackson包(版本需与你的Spring版本匹配,比如Spring 5.x对应Jackson 2.9+,Spring 6.x对应Jackson 2.12+):
jackson-core-x.x.x.jarjackson-databind-x.x.x.jarjackson-annotations-x.x.x.jar
2. 配置Spring的JSON消息转换器
如果使用XML配置(dispatcher-servlet.xml),需添加转换器配置:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="objectMapper"/> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
如果使用Java配置类,需注册转换器:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import com.fasterxml.jackson.databind.ObjectMapper; @Configuration @EnableWebMvc public class WebConfig { @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(new ObjectMapper()); return converter; } }
3. 可选:替换不可变列表
Arrays.asList()返回的是不可变内部列表,虽非报错直接原因,但可替换为普通ArrayList避免潜在问题:
public List<String> getFruits() { List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Pear")); return fruits; }
二、内置集合自动转JSON的说明
字符串数组、List等内置集合支持自动转JSON,但必须满足两个条件:
- 项目中存在完整的Jackson依赖
- Spring上下文已正确配置
MappingJackson2HttpMessageConverter(Spring Boot会自动配置,但纯Spring MVC需手动配置)
满足条件后,返回List<String>或String[]都会被自动序列化为JSON数组。
三、自定义类型列表的返回方式
返回自定义类型列表不需要强制使用ResponseEntity<T>,直接返回List<Student>即可,Spring会自动序列化。但ResponseEntity的优势在于可以灵活控制响应状态码、响应头,比如返回201创建成功、自定义响应头等。
示例1:直接返回自定义类型列表
先定义Student类:
public class Student { private Long id; private String name; private Integer age; // Jackson序列化需要无参构造器 public Student() {} public Student(Long id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } // Jackson需要Getter方法访问属性 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
控制器方法直接返回List
@GetMapping("/students") public List<Student> getStudents() { List<Student> students = Arrays.asList( new Student(1L, "Alice", 20), new Student(2L, "Bob", 21) ); return students; }
示例2:使用ResponseEntity返回自定义类型列表
如需控制响应状态码或头信息:
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @GetMapping("/students-with-status") public ResponseEntity<List<Student>> getStudentsWithStatus() { List<Student> students = Arrays.asList( new Student(1L, "Alice", 20), new Student(2L, "Bob", 21) ); // 添加自定义响应头,返回200 OK状态码 HttpHeaders headers = new HttpHeaders(); headers.add("X-Custom-Header", "Student-List"); return new ResponseEntity<>(students, headers, HttpStatus.OK); }
注意:自定义类需满足Jackson序列化要求:
- 有无参构造器
- 需要序列化的属性有Getter方法(或用
@JsonProperty注解标注字段)
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

