拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 HttpMessageNotWritableException:未找到类型返回值的转换器

HttpMessageNotWritableException:未找到类型返回值的转换器

白鹭 - 2021-11-24 467 0 0

1.概述

在本教程中,我们将阐明Spring的HttpMessageNotWritableException: “No converter found for return value of type”异常。

首先,我们将解释导致异常的主要原因。然后,我们将进行更深入的研究,以了解如何使用实际示例来制作它,以及最后如何修复它。

2.原因

通常,当Spring无法获取返回对象的属性时,将发生此异常。

导致此异常的最典型原因通常是,返回的对象的属性没有任何公共的getter方法

默认情况下,Spring Boot依靠Jackson库来完成所有序列化/反序列化请求和响应对象的繁重工作。

因此,导致我们异常的另一个常见原因可能是缺少或使用了错误的Jackson依赖项

简而言之,此类例外的一般准则是检查是否存在以下情况:

  • 默认构造函数
  • Getters方法
  • Jackson依赖

请记住, 异常类型已从java.lang.IllegalArgumentException更改为org.springframework.http.converter.HttpMessageNotWritableException.

3.实际例子

现在,让我们看一个生成org.springframework.http.converter.HttpMessageNotWritableException的示例:“未找到类型返回值的转换器”。

为了演示真实的用例,我们将使用Spring Boot构建一个用于学生管理的基本REST API。

首先,让我们创建模型类Student并假装忘记生成getter方法

public class Student {



 private int id;

 private String firstName;

 private String lastName;

 private String grade;



 public Student() {

 }



 public Student(int id, String firstName, String lastName, String grade) {


 this.id = id;


 this.firstName = firstName;


 this.lastName = lastName;


 this.grade = grade;

 }



 // Setters

 }

其次,我们将创建一个具有单个处理程序方法的Spring控制器,以按其id Student对象:

@RestController

 @RequestMapping(value = "/api")

 public class StudentRestController {



 @GetMapping("/student/{id}")

 public ResponseEntity<Student> get(@PathVariable("id") int id) {

 // Custom logic

 return ResponseEntity.ok(new Student(id, "John", "Wiliams", "AA"));

 }

 }

现在,如果我们使用CURL http://localhost:8080/api/student/1

curl http://localhost:8080/api/student/1

端点将发回此响应:

{"timestamp":"2021-02-14T14:54:19.426+00:00","status":500,"error":"Internal Server Error","message":"","path":"/api/student/1"}

查看日志,Spring抛出了HttpMessageNotWritableException

[org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class com.baeldung.boot.noconverterfound.model.Student]

最后,让我们创建一个测试用例,以查看未在Student类中定义getter方法时Spring的行为:

@RunWith(SpringRunner.class)

 @WebMvcTest(StudentRestController.class)

 public class NoConverterFoundIntegrationTest {



 @Autowired

 private MockMvc mockMvc;



 @Test

 public void whenGettersNotDefined_thenThrowException() throws Exception {



 String url = "/api/student/1";




 this.mockMvc.perform(get(url))


 .andExpect(status().isInternalServerError())


 .andExpect(result -> assertThat(result.getResolvedException())

 .isInstanceOf(HttpMessageNotWritableException.class))


 .andExpect(result -> assertThat(result.getResolvedException().getMessage())


 .contains("No converter found for return value of type"));

 }

 }

4.解决方案

防止异常的最常见解决方案之一是为我们要以JSON返回的每个对象的属性定义一个getter方法。

因此,让我们在Student类中添加getter方法并创建一个新的测试用例,以验证一切是否都能按预期工作:

@Test

 public void whenGettersAreDefined_thenReturnObject() throws Exception {



 String url = "/api/student/2";



 this.mockMvc.perform(get(url))

 .andExpect(status().isOk())

 .andExpect(jsonPath("$.firstName").value("John"));

 }

一个不明智的解决方案是将这些物业公开。但是,这不是100%安全的方法,因为它违反了一些最佳实践。

5.结论

在这篇简短的文章中,我们解释了导致Spring抛出org.springframework.http.converter.HttpMessageNotWritableException: ” No converter found for return value of type”

然后,我们讨论了如何产生异常以及如何在实践中解决该异常。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *