HttpMessageNotWritableException:找不到返回值的轉換器

Jackson,REST,Spring MVC
Remote
1
09:38 PM · Nov 30 ,2025

1. 概述

在本教程中,我們將深入瞭解 Spring 的 HttpMessageNotWritableException: “No converter found for return value of type” 異常。

首先,我們將解釋該異常的主要原因。然後,我們將深入研究如何使用一個實際示例來生成該異常,最後將學習如何修復它。

2. 導致原因

通常,此異常發生時,Spring 無法獲取返回對象的屬性。

此異常的最常見原因通常是 返回對象沒有為其屬性提供公共的 Getter 方法

Spring Boot 默認使用 Jackson 庫來處理請求和響應對象的序列化/反序列化任務。

因此,另一個 可能導致我們異常的原因是缺少或使用了錯誤的 Jackson 依賴項

簡而言之,對於此類異常的一般指導是檢查以下內容:

  • 默認構造函數
  • Getter 方法
  • 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]

最後,讓我們創建一個測試用例,以查看 Spring 在 getter 方法未定義時如何運行:

@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中返回的屬性定義一個獲取器方法。

因此,讓我們在 Student 類中添加獲取器方法,並創建一個新的測試用例來驗證一切是否按預期工作:

@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"));
}

一個不建議的解決方案是使屬性為公共,但是這種方法並不安全,因為它違背了許多最佳實踐。

5. 結論

在本文中,我們解釋了導致 Spring 拋出 org.springframework.http.converter.HttpMessageNotWritableException: “未找到轉換器用於返回類型” 的原因。

然後,我們討論瞭如何產生該異常以及如何在實踐中解決它。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.