Controller
Last updated
Last updated
Spring에서 Controller란 DispatcherServlet이 이용할 수 있도록 만들어진 요청
처리 도구이다.
다음 위치에 클래스를 생성한다.
이 컨트롤러를 등록하는 방법은 2가지가 존재한다. 1. servlet-context.xml에 등록하는 방법 2. @Controller를 사용하는 방법
@Controller를 class 윗줄에 추가하고 import를 수행한다.
이 문서에서는 2번 방법을 사용한다.
정상적으로 등록이 되었는지 확인하고 싶다면 spring explorer를 사용한다.
[Window] → [Show View] → [Other...] 선택한다.
검색창에 "spring explorer" 입력 후 [Spring Explorer] 선택한다.
해당 프로젝트에 컨트롤러가 잘 등록되어 있는지 확인한다.
다음 주소를 처리할 수 있는 메소드를 구현한다.
context path(artifactID)를 제외한 경로인 /test1
을 처리할 수 있도록 다음과 같이 메소드를 TestController에 구성한다
import까지 마치고 나면 요청을 처리할 수 있는 매핑이 한 개 생성된다. 서버에 프로젝트를 Add 한 뒤 위에 적힌 접속 주소를 브라우저를 켜서 접속하면 화면에 test1 호출이라는 글자가 나타나는 것을 확인할 수 있다.
작성한 매핑에 대해 살펴보면 다음과 같다.
/test1 경로로 들어온 요청을 처리하겠다고 명시하는 Annotation이다. 다음과 같이 작성하는 것이 원칙이지만 생략이 가능하여 일반적으로 생략하고 작성한다.
위와 같이 선언한 경우 GET/POST 등 전송방식을 고려하지 않고 해당 주소에 대한 모든 요청을 처리하게 된다.
@ResponseBody는 매핑에서 반환된 값이 화면에 그대로 출력된다는 의미이다. Spring에서 자체적으로 설정되어 있는 View Resolver를 무시하기 때문에 원하는 내용을 간단하게 테스트하거나 다운로드 등 기본 설정을 따르지 말아야 할 경우 사용한다.
메소드만으로는 의미가 없고 위에서 언급한 @RequestMapping, @ResponseBody와 조합하여 생각해야 의미가 있다.
/test1
이라는 요청이 발생하면 메소드가 실행된다.
실행이 완료되면 화면에 "test1 호출"이라는 글자를 출력하여 사용자에게 전송한다.
전송 방식 중 GET방식만 처리하고 싶은 경우에는 다음과 같이 매핑을 선언한다.
위의 매핑을 분석해보면
/test2
의 주소로 GET
방식 요청이 발생할 경우 test2 메소드가 실행된다.
실행이 완료되면 화면에 "test2 호출"이라는 글자를 출력하여 사용자에게 전송한다.
@RequestMapping 대신 Spring 4.3부터는 간단하게 사용할 수 있는 @GetMapping 이 있다.
전송 방식 중 POST 방식만 처리하고 싶은 경우에는 다음과 같이 매핑을 선언한다.
위의 매핑을 분석해보면
/test3
의 주소로 POST
방식 요청이 발생할 경우 test3 메소드가 실행된다.
실행이 완료되면 화면에 "test3 호출"이라는 글자를 출력하여 사용자에게 전송한다.
POST 방식은 직접 테스트가 어렵기 때문에 POSTMAN 등을 이용하여 테스트한다.
@RequestMapping 대신 @PostMapping을 사용할 수 있다(Spring 4.3 이상)
Spring에서는 다양한 방법으로 요청 파라미터를 처리할 수 있다.
예를 들어 다음과 같은 주소가 있다고 가정해보자.
이 요청주소에는 2개의 Parameter가 존재한다.
name = david
age = 20
이 파라미터를 받을 수 있도록 Mapping을 구현해본다.
기존 JSP 처럼 요청 객체를 매개변수에 선언하게 되면 Spring이 자동으로 주입해준다. Spring에서 Mapping을 만들 때에는 이처럼 다양한 객체들을 선언만으로 이용할 수 있다.
하지만 위의 코드는 가독성이 떨어지므로 Spring의 기능을 사용하면 다음과 같이 개선된다.
@RequestParam을 사용하면 파라미터를 변수에 바로 담도록 Spring에게 요청할 수 있다. 이름을 지정하거나 기본값을 지정할 수 있는 옵션을 가지고 있다. 위의 예시에서는 다음과 같이 요청했다고 생각해볼 수 있다.
/test5
로 접속하는 요청에 대해서 name이라는 이름의 파라미터를 String 변수에 담아라
/test5
로 접속하는 요청에 대해서 age라는 이름의 파라미터를 int 변수에 담아라
위의 조건이 만족되지 않을 경우 400 상태 오류가 발생한다. 만약 데이터가 없을 수도 있다면 다음과 같이 작성한다.
위의 매핑을 분석하면 다음과 같다.
/test6
으로 접속하는 요청에 대해서 name이라는 이름의 파라미터를 String 변수에 담아라(없으면 null로 설정하라)
/test6
으로 접속하는 요청에 대해서 age라는 이름의 파라미터를 int 변수에 담아라(없으면 0으로 설정하라)
@RequestParam만으로 받을 경우 데이터의 개수가 증가하면 변수를 많이 선언해야 하는 번거로움이 있다. 특히, 웹 페이지에서 기본적인 CRUD를 처리하다 보면 Database와 동일한 형태의 데이터(ex : DTO, VO)들을 전송하고 받아서 처리하는 경우가 많다. 이 때 @ModelAttribute를 이용하면 편하게 모든 데이터를 받을 수 있다.
클래스 파일 생성 : com.hakademy.spring08.entity.TestDto
클래스 안에 다음과 같은 구성 요소들을 배치하였다.
이름, 나이를 저장할 변수
기본 생성자
setter/getter 메소드
toString() 메소드 재정의
lombok을 이용하면 좀 더 간소화된 클래스를 만들 수 있지만 나중에 살펴보는 것으로 한다. 완성된 매핑 코드는 다음과 같다.
아래의 주소로 접속해보면 처리 여부를 확인할 수 있다.
@ResponseBody를 이용하면 화면에 글자를 출력할 수 있지만 홈페이지 화면과 같은 복잡한 내용들은 보여줄 수 없다. 따라서 다음과 같이 처리해야한다.
컨트롤러의 매핑에서 사용자의 요청을 처리한다.
요청을 처리한 뒤 보여줄 페이지의 이름을 반환한다.
페이지를 렌더링한다.
사용자에게 전송한다.
1번까지는 이전 코드들과 동일하지만 매핑에서 바로 사용자에게 출력하는 것이 아니라 뷰(View)를 불러서 2차 작업을 수행한 뒤 전송한다는 것이 차이점이라고 볼 수 있다.
프로젝트의 구조를 살펴보면 뷰 페이지의 위치를 알 수 있다.
경로는 webapp 부터 산정하므로 다음과 같이 작성할 수 있다.
servlet-context.xml에 보면 기본적으로 View Resolver가 등록된것을 확인할 수 있는데, 이 View Resolver가 자동으로 다음을 추가해준다.
접두사(Prefix) : /WEB-INF/views/
접미사(Suffix) : .jsp
따라서 컨트롤러에서는 접두사, 접미사를 제외한 순수한 이름만 반환하면 되므로 다음과 같이 처리할 수 있다.
/WEB-INF/views/test.jsp를 만든다(#jsp-생성)
http://localhost:8080/spring08/test8
을 처리할 수 있는 매핑을 생성한다.(#mapping-생성)
처리 후 반환 주소로 접두사, 접미사를 제외한 test
를 반환한다.
/WEB-INF/views/test.jsp
com.hakademy.spring08.TestController
View Resolver를 사용하기 위해서 @ResponseBody 는 제거한다. 따라서 반환값에 자동으로 접두사, 접미사가 추가되어 View페이지의 경로가 완성된다.
다음 주소로 접속하여 정상적으로 출력되는지 확인한다
컨트롤러에서 처리를 마치고 View page에 데이터를 전달하고 싶다면 Model 또는 ModelAndView를 사용할 수 있다. ModelAndView는 데이터와 뷰 정보가 합쳐진 객체이므로 여기서는 Model을 사용하여 처리하는 법을 살펴본다.
/WEB-INF/view/test9.jsp
를 생성하여 message
를 출력하도록 구현한다.
http://localhost:8080/spring08/test9
를 처리할 수 있는 매핑을 생성한다.
처리 코드 내에서 Model을 이용하여 데이터를 전달한다.
Model 에 있는 addAttribute() 를 이용한다.
message
라는 항목을 출력할 수 있도록 작성한다.
message
라는 항목을 전달하도록 작성한다.
다음 주소로 접속하여 확인하면 데이터가 잘 전달된 것을 알 수 있다.