스프링 웹 개발 기초
이 포스트는 김영한님의 ‘스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술’을 수강하고 작성하였습니다.
정적 컨텐츠
정적 컨텐츠는 서버에서의 별도 동작 없이 파일을 그대로 브라우저에 내려주는 것을 말한다.
스프링부트에서 정적 컨텐츠를 불러오는 과정
MVC와 템플릿 엔진
MVC = Model + View + Controller
템플릿 엔진은 HTML 파일을 그냥 브라우저에 전달하는 것이 아니라, 서버에서 별도의 동작을 한 후에 데이터를 동적으로 변환하여 전달한다.
스프링부트에서 템플릿 엔진을 이용한 요청 처리 과정
API
API는 json과 같은 포맷으로 클라이언트에 전달하는 방식이다. 주로 서버 - 서버가 데이터를 주고 받을 때 사용한다.
@ResponseBody 동작 원리
@ResponseBody
를 사용하면- HTTP의 BODY에 문자 내용을 직접 반환
viewResolver
대신HttpMessageConverter
가 동작- 기본 문자 처리:
StringHttpMessageConverter
- 기본 객체 처리:
MappingJackson2HttpMessageConverter
- byte 처리 등등 여러
HttpMessageConverter
가 기본으로 등록되어 있음
참고: 클라이언트의 HTTP Request의
accept
헤더와 서버의 컨트롤러 반환 타입을 조합해서 그에 맞는HttpMessageConverter
가 선택된다.
에러: Could not find acceptable representation
강의의 예제를 그대로 따라치면 재미없다는 생각이 있어서 강의 예제에 나온 코드를 살짝 비틀어서 아래와 같이 작성했는데, 바로 에러가 발생했다.
// 컨트롤러 내부에 작성
@GetMapping("hello-api")
@ResponseBody
public User helloAPI(@RequestParam(value = "name") String name) {
User user = new User(name);
return user;
}
static class User {
private String name;
public User(String name) {
this.name = name;
}
}
이런 식으로 코드를 작성했는데, 406 에러가 발생하며 Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
이런 메시지가 로그에 출력되었다. 응답 헤더에는 accept로 데이터의 형식을 지정해줄 수 있는데, accept에 지정되지 않은 데이터가 응답 메시지로 들어왔다는 것 같았다.
원인은 굉장히 간단했는데, User
클래스에 getter를 추가하지 않았기 때문이었다.
HttpMessageConverter에서 객체를 json으로 변환하는 과정에서 객체의 프로퍼티에 접근하려다보니 private
이라 접근하지 못했고, 제대로 json으로 변환되지 않은 상태에서 응답으로 처리된 것 같았다.
그래서! 과연 그게 정답인지 실험을 하나 해봤다.
// 컨트롤러 내부에 작성
@GetMapping("hello-api")
@ResponseBody
public User helloAPI(@RequestParam(value = "name") String name) {
User user = new User(name);
return user;
}
static class User {
public String name;
public User(String name) {
this.name = name;
}
}
위에 있던 코드와 달라진 점으로는 User
클래스에 getter/setter가 사라지고 생성자만 남았다는 것과, name
이 public
이라는 것.
이대로 실행해봤는데, 결과는 당연히 제대로 json 형식으로 응답을 전해주고 있었다.
댓글남기기