스프링 MVC의구조가 기존의 상속과, 인터페이스에서 어노테이션을 사용하는 방식으로 변한이후에
가장 큰 변화중 하나는 리턴타입이 자유로워 졌다는것.
Controller의 메서드가 사용할 수 있는 리턴 타입은 주로 다음과 같다.
-
String : jsp를 이용하는 경우 jsp파일의 경로와 파일이름을 나타내기 위해 사용한다.
-
void : 호출하는 URL과 동일한 이름의 jsp를 의미
-
VO.DTO타입: 주로 JSON타입의 데이터를 만들어서 반환하는 용도로 사용한다.
-
ResponseEntity 타입 : response할때 Http헤더 정보와 내용을 가공하는 용도로 사용한다.
-
Model, ModelAndView : Model로 데이터를 반환하거나 화면까지 같이 지정하는 경우에 사용한다.
-
HttpHeaders : 응답에 내용 없이 Http 헤더 메세지만 전달하는 용도로 사용한다.
void 타입
메서드의 리턴타입을 void로 지정하는경우 일반적인 경우에는 해당 URL의경로를 그대로 jsp 파일의 이름으로 사용하게 된다.
@GetMapping("/ex05")
public void ex05() {
log.info("/ex05......");
}
브라우저에서 SampleController의 경로에 ex05()의 경로를 합쳐 'sample/ex05'를 호출 하면 다음과 같은 결과를 보게 된다.
에러 메세지를 보면 원인이 'WEB-INF/views/sample/ex05.jsp'를 찾을 수 없어서 생기는 문제라는것을 볼 수있다.
이것은 servlet-context.xml의 아래 설정과 맞물려 URL경로를 View로 처리하기 때문에 생기는결과 이다.
Java설정의 경우
ServletConfig.java를 보자
String 타입
String타입은 상황에 따라 다른화면을 보여줄 필요가 있을때 유용하게 사용한다.
(if~ else와 같은 처리가 필요한 상황)
일반적으로 String 타입은 현재 프로젝트의 경우 JSP파일의 이름을 의미한다.
프로젝트 생성시 기본으로 만들어진 HomeController의코드를 보면 String을 반환타입으로 사용하는것을 볼 수 있다.
home()메서드는 "home"이라는 문자열을 리턴 했기때문에 경로는 '/WEB-INF/views/home.jsp'
경로가 된다.
String타입에는 다음과 같은 키워드를 붙여서 사용 할 수 있다.
- redirect: 리다렉트 방식으로 처리하는경우
- 웹컨테이너로 명령이 들어오면 다른 웹브라우저에게 다른 페이지로 가라고 명령을 내림
웹브라우저는 url을 지시된 주소로 바꾸고 해당 주소로 이동.
-> 최초 요청을 받은 URL1에서 클라이언트에게 redirect할 URL2를 리턴하고, 클라이언트에게 전혀 새로운 요청을 생성하여 URL2에 다시 요청을 보냄. 따라서 처음보냈던 최초의 요청정보는 더이상 유효하지 않게됨
- 웹컨테이너로 명령이 들어오면 다른 웹브라우저에게 다른 페이지로 가라고 명령을 내림
- forward: 포워드 방식으로 처리하는 경우
- 다음으로 이동할 URL로 요청정보를 그대로 전달, 사용자가 최초로 요청한 요청정보는 다음 URL에서도 유효
ex) forward 사용시 - 사용자가 보낸요청정보를 이용하여 글쓰기 기능시 만약 사용자가 글쓰기 응답페이지에서 새로고침을 누른다면 요청정보가 그대로 살아있기때문에 요청이 여러번 전달되어 동일한 게시물이 여러 번
등록 될 수있다. -> 게시판을 만들때는 시스템에 변화가 생기지 않는 단순한 조회 요청( select ) 의 경우
forward로 응답하는것이 바람직하다.
- 다음으로 이동할 URL로 요청정보를 그대로 전달, 사용자가 최초로 요청한 요청정보는 다음 URL에서도 유효
쾅쾅쾅 결론. 시스템(session,DB)에 변화가 생기는 요청(로그인,회원가입, 글쓰기)의경우 redirect방식으로 응답
시스템에 변화가 생기지 않는 단순조회는 forward로 응답.
객체타입
controller의 메서드 리턴타입을 VO(Value Object)나 DTO(Data Transfer Object) 타입등 복합적인 데이터가 들어간 객체 타입으로 지정 할 수있는데. 이 경우는 주로 JSON 데이터를 만들어내는 용도로 사용한다.
- 여기서 잠깐 vo와 dto의 차이에 대해 알아보겠다.
vo는
- 데이터 그 자체로 의미 있는 것을 담고 있는 객체이다.
- DTO와 동일한 개념이나 차이점은 Read–Only 속성 객체이다.
- 간단한 독립체( Entity )를 의미하는 작은 객체를 의미한다.
출처: https://ijbgo.tistory.com/9 [한량 개발자]
VO vs DTO
VO vs DTO VO(Value Object) - 데이터 그 자체로 의미 있는 것을 담고 있는 객체이다. - DTO와 동일한 개념이나 차이점은 Read–Only 속성 객체이다. - 간단한 독립체( Entit..
ijbgo.tistory.com
라고 한다.
dto는
- 전송되는 데이터의 컨테이너이다.
- VO와 동일하게 데이터를 저장하여 사용하도록 하는 부분에서 필요하다.
- VO와 비교를 하여 보면 DTO는 같은 시스템에서 사용되는 것이 아닌 다른 시스템으로 전달하는 작업을 처리하는 객체이다.
출처: https://ijbgo.tistory.com/9 [한량 개발자]
이해가 잘안가서 좀더 구글을 찾아보니
'외부 시스템과 데이터 통신을 할 경우에는 DTO로, DB에서 가져오는 Data는 VO로 정의해서 사용한다고 약속을 하면 될 것 같다.' 라는 글이 보였다. 이게 좀더 나에게 이해하기 쉬운 문장이다.
(회사 프로젝트에서 회원정보를 옮길일이있었는데 화면에 json타입으로 출력할때 controller에서 위 와같이 메소드리턴타입에 객체를 사용했던 적이 있다.)
이를 위해서는 jackson-databind라이브러리를 pom.xml에 추가한다. (json형식으로 출력하려면 필요하다)
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
SampleController에는 다음과 같은 메서드를 작성한다.
@GetMapping("ex06")
public @ResponseBody SampleDTO ex06() {
log.info("/ex06......");
SampleDTO dto = new SampleDTO();
dto.setAge(10);
dto.setName("홍길동");
return dto;
}
스프링 MVC는 자동으로 브라우저에 JSON타입으로 객체를 변환해서 전달한다.
http://localhost:8080/sample/ex06
개발자도구를 통해보면 서버에서 전송하는 MIME 타입이 'application/json' 으로 처리되는것을 볼 수있다.
스프링 MVC는 리턴타입에 맞게 데이터를 변환해주는 역할을 지정 할 수 있는데 기본적을 JSON은 처리가 되므로
별도의 설정이 필요하지 않다.
ResponseEntity타입
HTTP 프로토콜의 헤더를 다룰경우
스프링 MVC의 사상은 HttpServletRequest나 HttpServletResponse를 직접 핸들링 하지 않아도 이런 작업이 가능하도록 작성 되었기때문에 이러한 처리를 위해 ResponseEntity를 통해서 원하는 헤더정보나 데이터를 전달 할 수 있다.
SampleController의 일부
@GetMapping("ex07")
public ResponseEntity<String> ex07(){
log.info("/ex07....................");
// {"name": "홍길동"} "가 많아헷갈리니 이렇게하고 붙여넣자
String msg ="{\"name\": \"홍길동\"}";
HttpHeaders header = new HttpHeaders();
header.add("Content-Type", "application/json;charset=UTF-8");
return new ResponseEntity<>(msg,header,HttpStatus.OK);
}
만일 header선언부분이 오류가 난다면 import부분을 확인해보자
header는 spring이들어가는 클래스를 임포트해야한다. (org.springframework.http.HttpHeaders;)
ResponseEntity는 HttpHeader 객체를 같이 전달 할 수 있고. 이를 통해서 원하는 HTTP헤더 메세지를 가공하는것이 가능하다. ex07()의 경우 브라우저에는 JSON타입 이라는 헤더메시지와 200OK 라는 상태 코드를 전송한다.
'web' 카테고리의 다른 글
Part3 기본적인 웹게시물 관리 - 코드로배우는 스프링 웹프로젝트 (0) | 2020.10.29 |
---|---|
코드로 배우는 스프링 웹프로젝트 - 파일 업로드 처리 (0) | 2020.10.28 |
코드로 배우는 스프링웹프로젝트 - 06 스프링 MVC의 Controller (1) | 2020.10.19 |
코드로 배우는 스프링 웹프로젝트 -스프링 MVC의 기존 구조 (0) | 2020.10.05 |
코드로 배우는 스프링 웹프로젝트 - log4jdbc-log4j2 설정 (0) | 2020.10.01 |