19.

【Spring】@ResponseBodyアノテーションとは

編集
この記事の要点
  • @ResponseBodyメソッドの戻り値を HTTP レスポンスボディに直接書き出すアノテーション
  • デフォルトの View 解決をスキップして、戻り値を Jackson 等でJSON / XML に変換
  • @RestController = @Controller + @ResponseBody
  • クラス全体に効かせるなら @RestController、特定メソッドだけなら @ResponseBody

 

@ResponseBody とは

通常の Spring MVC では、@Controller のメソッドは戻り値を「View 名」と解釈し、ViewResolver が JSP / Thymeleaf 等のテンプレートを探します。

@ResponseBody を付けると、この View 解決をスキップし、戻り値をそのままレスポンスボディに書き出します。HttpMessageConverter(Jackson 等)が JSON / XML に変換します。

基本的な使い方

メソッドレベル

@Controller
public class UserController {

    @GetMapping("/users/{id}")
    @ResponseBody  // ← この戻り値だけ JSON で返す
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @GetMapping("/users/list")
    public String listView() {
        return "users/list";  // ← こちらは View 名 (users/list.jsp 等)
    }
}

クラスレベル(@RestController)

すべてのメソッドが API レスポンスを返すなら @RestController が便利:

@RestController  // = @Controller + @ResponseBody
@RequestMapping("/api/users")
public class UserApiController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {  // @ResponseBody 不要
        return userService.findById(id);
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.create(user);
    }
}

レスポンス形式(JSON / XML / その他)

戻り値の変換は HttpMessageConverter が担当します。クライアントが Accept ヘッダで何を要求しているかで形式が決まる:

Accept ヘッダ変換必要な依存
application/jsonJackson / Gson で JSONSpring Boot に標準同梱(Jackson)
application/xmlJAXB / Jackson XML で XMLjackson-dataformat-xml 追加
text/plainString そのまま標準
text/htmlString そのまま(HTML として解釈)標準

レスポンスステータスとヘッダの制御

① @ResponseStatus

@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)  // 201
public User create(@RequestBody User user) {
    return userService.create(user);
}

② ResponseEntity(細かい制御)

@GetMapping("/users/{id}")
public ResponseEntity getUser(@PathVariable Long id) {
    Optional user = userService.findByIdOptional(id);
    return user
        .map(u -> ResponseEntity.ok()
            .header("X-Custom-Header", "value")
            .body(u))
        .orElseGet(() -> ResponseEntity.notFound().build());
}

// 簡潔形
return ResponseEntity.status(HttpStatus.CREATED).body(user);
return ResponseEntity.noContent().build();  // 204
return ResponseEntity.badRequest().body(errorDto);  // 400

JSON 出力のカスタマイズ

① Jackson アノテーションで制御

public class User {
    private Long id;

    @JsonProperty("user_name")  // JSON のキー名変更
    private String name;

    @JsonIgnore  // JSON 出力から除外
    private String password;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate birthDate;

    @JsonInclude(JsonInclude.Include.NON_NULL)  // null は出力しない
    private String email;
}

② application.properties での共通設定

# キーをスネークケースに
spring.jackson.property-naming-strategy=SNAKE_CASE

# null は出力しない
spring.jackson.default-property-inclusion=non_null

# 日付フォーマット
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Asia/Tokyo

@ResponseBody vs @RestController vs @Controller

用途使うもの
API のみのクラス@RestController
HTML View のみのクラス@Controller
HTML View + 一部 API(混在)@Controller + 一部メソッドに @ResponseBody

よくあるトラブル

Q. JSON でなく文字列がそのまま返る

  • 戻り値が String 型: そのまま text/plain で返る → DTO に変えるか、明示的に JSON 形式で返す
  • Jackson が classpath にない: spring-boot-starter-web を依存に追加

Q. レスポンスが空 ({})

  • getter がない: Jackson は getter を見るので必須
  • Lombok の @Data@Getter で getter 生成

Q. 文字化け(日本語が ???)

# application.properties
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. @After
  2. @Autowired
  3. @Bean
  4. @Before
  5. @Column
  6. @Component
  7. @Configuration
  8. @Controller
  9. @Data
  10. @Entity
  11. @GeneratedValue
  12. @Id
  13. @Modifying
  14. @PathVariable
  15. @PropertySource
  16. @Repository
  17. @RequestBody
  18. @RequestMapping
  19. @ResponseBody
  20. @RestController
  21. @Service
  22. @SpringBootApplication
  23. @Table
  24. @Transactional
  25. @Value