인프런 김영한 강사님의 스프링MVC 강의를 듣고학습한 내용을 정리한 게시물입니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
컨트롤러를 이용하여 요청을 전달받고, 웹페이지에 응답을 작성하거나 뷰를 반환하기도 한다. 요청을 전달받을 때, 우리는 특정 주소로 매핑을 해야하며, 웹페이지에 응답을 띄울지 뷰를 보여줄지 정해야한다.
1. @Controller와 @RestController
앞서 말했듯이 반환형식을 정해야하는데, 이때 @Controller와 @RestController를 알아야한다.
@Controller
@Controller는 반환 값이 String이면 뷰 이름으로 인식한다. 그래서 반환한 문자열과 같은 이름을 가진 뷰가 렌더링된다. 즉, 주로 뷰를 반환하기 위해 사용한다는 것이다.
예를 들어 아래 코드에서는 basic 패키지에 있는 items라는 뷰를 반환한다.
@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {
private final ItemRepository itemRepository;
@GetMapping
public String items(Model model) {
List<Item> items = itemRepository.findAll();
model.addAttribute("items", items);
return "basic/items";
}
...
}
참고로 응답으로 보여줄 뷰, 즉 동적html은 resource/templates 패키지에 넣어주면 된다. (내 IntelliJ 기준 ...)
찾아보니 @Controller로 뷰 뿐만 아니라 데이터를 반환할 수도 있다고 한다. return에 String타입을 쓰게 되면 뷰 이름으로 인식하지만, 객체를 반환하면 Json으로 바꾸어 반환할 수 있다고 한다!!
객체를 반환하기 위해서는 viewResolver가 아닌 HTTP 메시지 컨버터 (HttpMessageConverter)를 사용한다.
HttpMessageConverter 인터페이스
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
이 인터페이스는 요청, 응답에 모두 사용된다.
- canRead(), canWrite() : 메시지 컨버터가 해당 클래스, 타입을 지원하는지 확인 ->> 사용전 체크할 때 좋을 것같다.
- read(), write() : 메시지 컨버터를 통해 메시지 읽고 쓰는 기능
우리가 처리해아하는 데이터의 타입에 따라 사용되는 컨버터가 달라진다. 스프링 부투는 대상 클래스타입과 미디어타입을 체크해 사용 여부를 결정하게 된다.
몇가지 주요 메시지 컨버터를 알아보자
- 기본 문자처리 (단순 문자열) : StringHttpMessageConverter
- 클래스타입 : String, 미디어타입 : */* (암거나 가능하다는 뜻이다)
- 객체처리 : MappingJackson2HttpMessageConverter
- 클래스타입 : 객체 또는 HashMap, 미디어타입 : application/json 관련
- 바이트배열 : ByteArrayHttpMessageConverter
- 클래스타입 : byte[] , 미디어타입 : */*
@RestController
@RestController는 @Controller에 @ResponseBody가 추가된 것이다. 이는 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력한다.
이렇게 코드를 작성한다면 user() 가 실행되었을 때 Http 바디에 "get users"라는 문자가 띄워진다.
그럼 저 메소드가 언제 되는건데 ?
2. @RequestMapping
@RequestMapping을 통해 요청과 메소드를 매핑할 수 있다. 주로 value와 method을 사용한다.
value ?
value에는 요청받을 url을 넣어준다.
method ?
method에는 어떤 요청을 받을지 넣어준다! POST, GET, DELETE같은..
메소드 속성을 지정하지 않으면 모두 허용하게 된다.
@RequestMapping(value = "/hello-basic", method = RequestMethod.GET)
public String helloBasic() {
log.info("helloBasic");
return "ok";
}
@GetMapping(value = "/hello-basic")
public String helloBasic() {
log.info("helloBasic");
return "ok";
}
첫 코드블럭처럼 value와 method 속성을 지정해도 되지만, 메소드에 따른 매핑 애노테이션이 따로 있다. GetMapping뿐만 아니라 PutMapping, PatchMapping, DeleteMapping 등 축약 애노테이션을 모두 제공한다!
속성은 value와 method를 가장 많이 사용하지만, 몇가지 더 소개하자면 아래와 같은 것들이 있다.
params
이 속성은 특정 파라미터 조건 매핑이다. 특정 파라미터가 있어야 매핑이 된다.
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
log.info("mappingParam");
return "ok";
}
이런식으로 사용할 수 있다. 그러나 잘 사용하지는 않는다고 한다.
headers
이 속성은 특정 헤더 조건 매핑이다. 헤더에 특정 조건이 들어가있어야 하고 이는 postman으로 테스트 해야한다.
consumes, produces
이 속성들은 미디어 타입 조건 매핑이다. consumes는 받는 데이터타입을 지정하고, produces는 보내는 데이터 타입을 지정한다.
이번에는 사용자에게 입력받은 것을 파라미터로 쉽게 사용하는 방법을 작성하려 한다.
3. @RequestParam
이 애노테이션을 사용하면 요청 파라미터를 아주 편리하게 쓸 수 있다.
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParamV2(@RequestParam("username") String username,
@RequestParam("age") int age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
/*
param이랑 이름 똑같이 지으면 생략 가능
*/
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(@RequestParam String username,
@RequestParam int age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
@RequestParam() 안에 http 파라미터 이름을 써주고, 변수 이름도 별도로 사용할 수 있다. 만약 변수이름과 파라미터 이름이 같다면, ()내부를 생략하여 두번째 코드블럭처럼 써줄 수 있다.
이 애노테이션의 속성 중 required라는 속성을 이용해 해당 파라미터값의 필수 여부도 지정할 수 있다.
- required=true : 파라미터 필수
- required = false : 파라미터 필수 X
기본값은 true로 설정되어있다.
만약 int인 age를 false로 지정하게 되면 null이 되었을 때 예외가 발생한다. int는 기본형이라 null이 들어올 수 없기 때문에!!
이럴 경우에는 age의 타입을 Integer로 바꾸거나, defaultValue를 설정해주면 된다. 이것도 @RequestParam의 속성 중 하나이다.
'백엔드 > 스프링 MVC' 카테고리의 다른 글
[Spring MVC] 4. REQUEST와 RESPONSE에 관하여 (HttpServletRequest, HttpServletResponse..) - (1) Request (2) | 2024.09.13 |
---|---|
[Spring MVC] 1. 스프링 MVC 기초 정리 (스레드와 스레드풀) - (2) (0) | 2024.07.08 |
[Spring MVC] 3. 요청 매핑하기 - (2) (@ModelAttribute, ServletInputStream과 HttpEntity) (0) | 2024.04.08 |
[Spring MVC] 2. 스프링 MVC 구조 (0) | 2024.03.30 |
[Spring MVC] 1. 스프링 MVC 기초 정리 (MVC패턴, 서블릿, WAS) - (1) (1) | 2024.03.28 |