개발하는 삶
[Spring] HTTP 요청/응답 본문
HTTP 응답 - 정적 리소스, 뷰 템플릿, HTTP 메시지 사용
- 정적 리소스
- 정적인 HTML, css, js 제공할 때
- 경로
- 스프링 부트는 /static, /public, /resources, /META-INF/resources 디렉토리에 있는 정적 리소스 제공
- 정적리소스가 공개되는 /resources/static 폴더에 HTML을 넣어두면
- 실제 서비스에서도 공개되기 때문에, 공개할 필요가 없는 HTML인지 확인하자
- src/main/resources/static/basic/hello-form.html 에 파일이 있을 때
- 웹 브라우저에서는 http://localhost:8080/basic/hello-form.html 으로 실행하면 됨
- 스프링 부트는 /static, /public, /resources, /META-INF/resources 디렉토리에 있는 정적 리소스 제공
- 뷰 템플릿
- 동적인 HTML 제공할 때
- 뷰 템플릿을 거쳐 HTML 생성 -> 뷰가 응답을 만들어 전달
- 뷰 템플릿 경로 : src/main/resources/templates
- HTTP 메시지 바디
- HTTP API에서 주로 사용. HTML이 아니라 데이터를 전달해야 함.
- 따라서 HTTP 메시지 바디에 JSON 같은 형식으로,
- 정적 리소스, 뷰 템플릿을 거치지 않고 데이터를 직접 담아 보냄
뷰 템플릿을 호출하는 컨트롤러
- String을 반환하는 경우 - View or HTTP 메시지
// 뷰의 논리적 주소 response/hello 로 응답하는 법 (hello.html 실행하는 게 목적)
//@ResponseBody가 없으면 response/hello 로 뷰 리졸버가 실행됨
//@ResponseBody가 있으면 뷰 리졸버를 실행X. HTTP 메시지 바디에 직접 response/hello 문자 입력.
@Controller
public class ResponseViewController {
@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
ModelAndView mav = new ModelAndView("response/hello").addObject("data", "hello!");
return mav;
}
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
model.addAttribute("data", "hello!!");
return "response/hello";
}
@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
model.addAttribute("data", "hello!!");
}
}
HTTP 메시지 컨버터
- HTTP API 처럼 JSON 데이터를 HTTP 메시지 바디에서 직접 읽거나 쓰는 경우
- -> 메시지 컨버터를 이용하기
- HTTP 요청 : @RequestBody, HttpEntity(RequestEntity)
- HTTP 요청이 오면 컨트롤러에서 @RequestBody, HttpEntity(RequestEntity) 사용
- 해당 클래스/미디어타입을 지원하는 지 체크 -> 조건 만족 후 객체 생성/반환
- HTTP 응답 : @ResponseBody, HttpEntity(ResponseEntity)
- 컨트롤러 -> @ResponseBody, HttpEntity(ResponseEntity) 값 반환됨
- 메시지를 쓸 수 있는지 체크 -> 조건 만족 후 HTTP 응답 메시지 바디에 데이터 생성
- 검증
- 메시지 컨버터가 참조한 대상 클래스/미디어 타입 둘을 체크 후 사용여부 결정
- byte[] 타입
- 요청 예시) @RequestBody byte[] data
- 응답 예시) @ResponseBody return byte[]
- String 타입
- 요청 예시) @RequestBody String data
- 응답 예시) @ResponseBody return "ok"
- application/json 타입
- 요청 예시) @RequestBody HelloData data
- 응답 예시) @ResponseBody return helloData
- @ResponseBody 사용
- HTTP의 Body에 문자 내용을 직접 반환
- 뷰 리졸버 -> 대신 HttpMessageConverter 가 동작
- 기본 문자처리
- @RestController
- 해당 컨트롤러에 모두 @ResponseBody 가 적용됨
- JSON 형태로 객체 데이터 반환
@Slf4j
@Controller
//@RestController
//만약 @RestController 사용 -> 해당 컨트롤러에 모두 @ResponseBody가 적용됨
public class ResponseBodyController {
//서블릿 직접 다룰때처럼 HTTP 메시지 바디에 직접 응답 전달
@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException
{
response.getWriter().write("ok");
}
/**
* HttpEntity, ResponseEntity(Http Status 추가)
* @return
*/
//ResponseEntity => HttpEntity 상속 (HTTP 메시지의 헤더, 바디정보 가짐) + 응답코드 설정
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
//응답 메시지, 응답코드
return new ResponseEntity<>("ok", HttpStatus.OK);
}
//@ResponseBody 를 사용시 view 사용 안하고,
//메시지 컨버터를 통해 HTTP 메시지를 직접 입력할 수 있음
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
//ResponseEntity를 반환. HTTP 메시지 컨버터를 통해 JSON 형식으로 변환되어 반환
@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return new ResponseEntity<>(helloData, HttpStatus.OK);
}
//@ResponseBody 를 사용 + @ResponseStatus(HttpStatus.OK) 로 응답코드 설정
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
}
RequestMappingHandlerAdapter 동작 방식
HTTP 메시지 컨버터
요청의 경우 : HTTP 메시지 컨버터를 사용해 필요한 객체를 생성해줌
응답의 경우 : HTTP 메시지 컨버터를 호출해 응답결과를 만듬
출처
'Spring' 카테고리의 다른 글
[Spring] servlet (0) | 2022.08.18 |
---|---|
[Spring] 로그인, 스프링 시큐리티 (0) | 2022.08.18 |
[Spring] 스프링 MVC (0) | 2022.07.20 |
[Spring] HTTP Method (0) | 2022.07.11 |
[Spring] 웹서버 (0) | 2022.07.09 |