1. 소개
Spring을 사용하면 일반적으로 HTTP 응답을 미세 조정하는 것을 포함하여 동일한 목표를 달성하는 여러 가지 방법이 있습니다.
이 짧은 사용방법(예제)에서는 ResponseEntity 를 사용하여 HTTP 응답의 본문, 상태 및 헤더를 설정하는 방법을 살펴봅니다 .
2. ResponseEntity
ResponseEntity 는 전체 HTTP 응답(상태 코드, 헤더 및 본문)을 나타냅니다 . 결과적으로 HTTP 응답을 완전히 구성하는 데 사용할 수 있습니다.
사용하고 싶다면 엔드포인트에서 반환해야 합니다. Spring은 나머지를 처리합니다.
ResponseEntity 는 일반 유형입니다. 결과적으로 모든 유형을 Response body으로 사용할 수 있습니다.
@GetMapping("/hello")
ResponseEntity<String> hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}
프로그래밍 방식으로 응답 상태를 지정하므로 다양한 시나리오에 대해 다른 상태 코드로 반환할 수 있습니다.
@GetMapping("/age")
ResponseEntity<String> age(
@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return new ResponseEntity<>(
"Year of birth cannot be in the future",
HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(
"Your age is " + calculateAge(yearOfBirth),
HttpStatus.OK);
}
또한 HTTP 헤더를 설정할 수 있습니다.
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}
또한 ResponseEntity 는 HeadersBuilder 와 해당 하위 인터페이스인 BodyBuilder 의 두 가지 중첩 빌더 인터페이스를 제공합니다 . 따라서 ResponseEntity 의 정적 메서드를 통해 해당 기능에 액세스할 수 있습니다 .
가장 간단한 경우는 본문과 HTTP 200 응답 코드가 있는 응답입니다.
@GetMapping("/hello")
ResponseEntity<String> hello() {
return ResponseEntity.ok("Hello World!");
}
가장 인기 있는 HTTP 상태 코드 의 경우 정적 메서드를 얻습니다.
BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder<?> noContent();
HeadersBuilder<?> notFound();
BodyBuilder ok();
또한 BodyBuilder 상태(HttpStatus 상태) 및 BodyBuilder 상태(int 상태) 메서드를 사용하여 HTTP 상태를 설정할 수 있습니다.
마지막으로 ResponseEntity<T> BodyBuilder.body(T body) 를 사용하여 HTTP Response body을 설정할 수 있습니다.
@GetMapping("/age")
ResponseEntity<String> age(@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return ResponseEntity.badRequest()
.body("Year of birth cannot be in the future");
}
return ResponseEntity.status(HttpStatus.OK)
.body("Your age is " + calculateAge(yearOfBirth));
}
사용자 정의 헤더를 설정할 수도 있습니다.
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set");
}
BodyBuilder.body() 는 BodyBuilder 대신 ResponseEntity 를 반환 하므로 마지막 호출이어야 합니다.
HeaderBuilder 를 사용 하면 Response body의 속성을 설정할 수 없습니다.
컨트롤러에서 ResponseEntity<T> 개체를 반환하는 동안 요청을 처리하는 동안 예외 또는 오류가 발생할 수 있으며 오류 관련 정보를 다른 유형(예: E)으로 표시되는 사용자 에게 반환하려고 합니다 .
Spring 3.2는 이러한 종류의 시나리오를 처리 하는 새로운 @ControllerAdvice 어노테이션 으로 전역 @ExceptionHandler 에 대한 지원을 제공합니다. 자세한 내용은 여기에서 기존 문서를 참조하십시오 .
ResponseEntity 는 매우 강력 하지만 남용해서는 안 됩니다. 간단한 경우에 우리의 요구를 충족시키는 다른 옵션이 있으며 훨씬 더 깔끔한 코드를 생성합니다.
3. 대안
3.1. @ResponseBody
클래식 Spring MVC 애플리케이션에서 엔드포인트는 일반적으로 렌더링된 HTML 페이지를 반환합니다. 때로는 실제 데이터만 반환하면 됩니다. 예를 들어 AJAX와 함께 엔드포인트를 사용할 때입니다.
이러한 경우 요청 핸들러 메소드를 @ResponseBody 로 표시할 수 있으며 Spring은 메소드의 결과 값을 HTTP Response body 자체로 취급합니다.
자세한 내용은 이 문서에서 시작하는 것이 좋습니다 .
3.2. @ResponseStatus
엔드포인트가 성공적으로 반환되면 Spring은 HTTP 200(OK) 응답을 제공합니다. 엔드포인트에서 예외가 발생하면 Spring은 사용할 HTTP 상태를 알려주는 예외 핸들러를 찾습니다.
이러한 메소드를 @ResponseStatus로 표시할 수 있으므로 Spring 은 사용자 정의 HTTP 상태로 리턴합니다 .
더 많은 예를 보려면 사용자 지정 상태 코드 에 대한 문서를 참조하세요 .
3.3. 응답을 직접 조작
Spring은 또한 우리가 javax.servlet.http.HttpServletResponse 객체에 직접 접근할 수 있게 해줍니다 . 메서드 인수로 선언하기만 하면 됩니다.
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}
Spring은 기본 구현 위에 추상화와 추가 기능을 제공하기 때문에 이러한 방식으로 응답을 조작해서는 안 됩니다.
4. 결론
이 기사에서 우리는 Spring에서 HTTP 응답을 조작하는 여러 방법에 대해 논의하고 장점과 단점을 조사했습니다.
평소와 같이 예제는 GitHub에서 사용할 수 있습니다 .