web.xml에 등록되어 있는 front controller를 이용해 만들어 줄 것이다.

web.xml

servlet-context.xml은 appServlet 이름의 서블릿(Front Controller)에게 제공될 Spring Bean을 등록하기 위한 Bean Configuration File이다.
InternalResourceViewResolver 객체
: 클라이언트 요청에 의해 호출되는 요출 처리 메소드의 반환값(View name)을 제공받아 응답 처리할 JSP 문서로 변환하여 반환하는 기능을 제공한다.
component-scan 엘리먼트
: 스프링 컨테이너가 클래스에서 사용한 스프링 어노테이션을 검색하여 패키지를 제공해준다.
- base-package 속성 : 스프링 어노테이션을 사용한 클래스가 선언된 패키지를 설정한다.
annotation-driven 엘리먼트
: @Controller 어노테이션으로 등록된 Spring Bean에서 @RequestMapping 어노테이션으로 등록된 요청 처리 메소드를 클라이언트 요청에 의해 호출되어 실행될 수 있도록 설정한다.
- HandlerMapping 객체를 사용하지 않아도 클라이언트 요청에 의해 Controller 클래스의 요청 처리 메소드가 호출되도록 매핑 설정해준다.
servlet-context.xml


controller 패키지에 요청 처리 클래스(Controller 클래스)를 작성해보자
@Controller 어노테이션를 이용해 요청 처리 클래스를 Spring Bean으로 등록한다.
- 클래스의 이름은 Spring Bean의 식별자(beanName)으로 자동 설정된다. (첫문자는 소문자로 변환)
- value 속성을 사용하여 Spirng Bean의 식별자(beanName)를 변경 할 수 있다.
- @Controller 어노테이션을 사용하면 Controller 인터페이스를 상속받지 않아도 요청 처리 클래스로 처리가 가능하다.
- @RequestMapping 어노테이션을 사용하여 메소드를 요청 처리 메소드로 처리되도록 작성할 수 있다.
- @RequestMapping 어노테이션을 사용하여 요청 처리 메소드를 여러개 선언할 수 있다. Contoller 클래스를 여러 개 만들지 않아도 되기 때문에 편리하다.
@RequestMapping은 클라이언트 요청을 처리하기 위한 메소드를 선언하기 위한 어노테이션이다.
- 기본적으로 클라이언트의 모든 요청방식(Method - GET, POST, PUT, CATCH, DELETE)에 의해 호출되는 요청 처리 메소드를 작성할 경우 사용한다.
- 클라이언트의 요청방식을 구분하여 요청 처리 메소드를 호출하고자 할 경우 @RequestMapping 대신 @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping 등의 어노테이션을 사용할 수 있다. (주로 REST 프로그램 만들 때 사용)
- value 속성에 클라이언트 요청 정보(URL 주소)를 반드시 설정해주어야 한다.
- 클라이언트의 요청 URL 주소로 Front Controller에 의해 요청 처리 메소드가 자동으로 호출된다. (요청 처리)
- 다른 속성이 없는 경우 속성값만 설정 가능하다.
- 다른 요청 처리 메소드의 value 속성값과 중복될 경우 WAS 프로그램 시작시 에러가 발생한다.
요청 처리 메소드 안에 요청 처리 명령을 작성할 때 일반적으로 Service 클래스의 메소드를 호출한다.
예제에서는 Service 클래스가 없으므로 log로 작성할 것이다.
@Controller
public class HelloController {
//@RequestMapping를 반드시 선언해주어야 한다
@RequestMapping(value = "/hello")//클라이언트가 hello라고 요청했을 때 실행
public void hello() {//요청 처리 메소드
//요청 처리 명령 작성 - Service 클래스의 메소드 호출
log.info("[/hello] 페이지 요청 : HelloController 클래스의 hello() 메소드 호출");
}
...
}
요청 처리 메소드는 Front Controller에게 반드시 뷰이름(ViewName)을 제공해야 한다.
→ Front Controller는 제공받은 뷰이름을 이용하여 ViewResolver 객체로 응답 처리되도록 변환할 것이다.
1. 메소드의 반환형을 [void]로 설정한 경우 Front Controller에게 메소드의 이름을 뷰이름으로 제공한다. (예제의 경우 hello가 뷰이름이 된다)

hello.jsp 파일이 존재해야 응답이 가능하다.
hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>Hello, Srping!</h1>
<hr>
</body>
</html>
HelloController을 실행하고 http://localhost:8000/controller/hello 로 주소 설정해주면

잘 출력되는 것을 확인할 수 있다.
src/main/resources의 log4j.xml 파일에서 "xyz.itwill10.controller" 패키지에서 info 레벨 이상의 로그만 출력하도록 지정할 수 있다.


2. 메소드의 반환형을 [String]로 설정한 경우 Front Controller에게 메소드의 반환값(문자열)을 뷰이름으로 제공한다.
@RequestMapping("/helloViewName")
public String helloViewName() {
log.info("[/helloViewName] 페이지 요청 : HelloController 클래스의 helloViewName() 메소드 호출");
return "hello";
}


3. 메소드의 반환형을 [ModelAndView]로 작성한 경우 반환된 ModelAndView 객체에 뷰이름을 저장하여 제공한다.
ModelAndView : 처리결과를 속성값으로 저장하고 뷰이름(ViewName)을 저장하기 위한 객체
@RequestMapping("/helloMav")
public ModelAndView helloModelAndView() {
log.info("[/helloMav] 페이지 요청 : HelloController 클래스의 helloModelAndView() 메소드 호출");
//ModelAndView modelAndView=new ModelAndView();
//modelAndView.setViewName("hello");//Setter 메소드 뷰이름 변경
ModelAndView modelAndView=new ModelAndView("hello");//생성자로 뷰이름 변경
return modelAndView;
}


세 가지 방법 중에서는 String을 가장 많이 사용한다.
Front Controller가 InternalResourceViewResolver를 사용한 경우 뷰이름으로 생성된 JSP 문서로 응답하지만
Front Controller가 BeanNameViewResolver를 사용한 경우 Spring Bean으로 응답 처리할 수 있도록 만들 수 있다.
→ 요청 처리 메소드의 반환형을 Map 인터페이스 또는 Model 인터페이스로 설정할 수 있다.
(추후 BeanNameViewResolver 배운 뒤 볼 것임)
요청 처리 메소드에 의해 처리될 결과를 뷰(JSP 문서)에게 제공하는 방법
1.ModelAndView 객체의 addObject 메소드를 호출하여 처리결과를 속성값으로 저장하여 제공할 수 있다.
ModelAndView.addObject(String attributeName, Object attributeValue)
- ModelAndView 객체에 처리결과를 속성값으로 저장하는 메소드 - Request Scope
- 뷰(JSP 문서)에서는 EL 또는 JSTL를 사용하여 속성명으로 속성값을 제공받아 사용할 수 있다.
//요청 처리 메소드에 의해 처리될 결과를 뷰(JSP 문서)에게 제공하는 방법
//요청 처리 클래스 - Spring Bean으로 등록
@Controller
public class ResultController {
@RequestMapping("/resultMav")
public ModelAndView modelAndViewResult() {
ModelAndView modelAndView=new ModelAndView("result_display");
//ModelAndView 객체에 처리결과를 속성값으로 저장
modelAndView.addObject("mavName", "홍길동");
return modelAndView;
}
}
result_display.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>출력페이지</h1>
<hr>
<h2>ModelAndView = ${mavName }</h2>
</body>
</html>

요청 처리 메소드는직접 호출하는 것이 아니라 Front Controller에 의해 자동 호출되는 메소드이다.
요청 처리 메소드에 매개변수를 작성하면 Front Controller는 스프링 컨테이너(WebApplicationContext 객체)에게 매개변수에 저장 가능한 객체(Spring Bean)를 제공받아 저장할 수 있다.
@RequestMapping("/resultMav")
public ModelAndView modelAndViewResult(ModelAndView modelAndView) {
modelAndView.setViewName("result_display");
modelAndView.addObject("mavName", "홍길동");
return modelAndView;
}

2.HttpServletRequest 객체의 setAttribute() 메소드를 호출하여 처리결과를 속성값으로 저장하여 제공힌다.
HttpServletRequest.setAttribute(String attribute, Object attributeValue)
: HttpServletRequest 객체에 처리결과를 속성값으로 저장하는 메소드 - Request Scope
@RequestMapping("/resultRequest")
public String requestResult(HttpServletRequest request) {
request.setAttribute("requestName", "임꺽정");
return "result_display";
}
result_display.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>출력페이지</h1>
<hr>
<h2>ModelAndView = ${mavName }</h2>
<h2>HttpServletRequest = ${requestName }</h2>
</body>
</html>

3.Model 객체의 addAttribute() 메소드를 호출하여 처리결과를 속성값으로 저장하여 제공한다.
Model 객체 : 처리결과를 속성값으로 저장하여 뷰에게 제공하기 위한 객체
model.addAttribute() : Model 객체에 처리결과를 속성값으로 저장하는 메소드 - Request Scope
@RequestMapping("/resultModel")
public String modelResult(Model model) {
model.addAttribute("modelName", "전우치");
return "result_display";
}
result_display.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>출력페이지</h1>
<hr>
<h2>ModelAndView = ${mavName }</h2>
<h2>HttpServletRequest = ${requestName }</h2>
<h2>Model = ${modelName }</h2>
</body>
</html>

ModelController
@Controller
public class ModelController {
@RequestMapping("/display1")
public String display1(Model model) {
model.addAttribute("name", "홍길동");
model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
@RequestMapping("/display2")
public String display2(Model model) {
model.addAttribute("name", "임꺽정");
model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
@RequestMapping("/display3")
public String display3(Model model) {
model.addAttribute("name", "전우치");
model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
}
model_display.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>출력페이지</h1>
<hr>
<h2>이름 = ${name }</h2>
<h2>현재 날짜와 시간 = ${now }</h2>
</body>
</html>



model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
>> 해당 부분이 겹치기 때문에 비효율적이다.
이를 한꺼번에 처리하는 방법에 대해 알아보자
@ModelAttribute
- 메소드에 @ModelAttribute 어노테이션을 사용하면 메소드에 반환되는 객체(값)을 현재 Controller 클래스에 작성된 모든 요청 처리 메소드의 뷰에게 제공해준다.
- 요청 처리 메소드에 의해 응답 처리될 뷰에서 공통적으로 사용되는 객체(값)를 제공할 목적으로 사용한다.
- value 속성에 메소드에 의해 반환된 객체(값)을 뷰에서 사용하기 위한 이름(속성명)을 설정한다. (다른 속성이 없으면 속성값만 설정 가능하다.)
@Controller
public class ModelController {
...
//메소드에 반환되는 객체(값)을 현재 Controller 클래스에 작성된 모든 요청 처리 메소드의 뷰에게 제공
@ModelAttribute(value = "now")
//시스템의 현재 날짜와 시간을 문자열로 반환하는 메소드
public String getNow() {
return new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date());
}
}
전체 소스코드
package xyz.itwill10.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ModelController {
@RequestMapping("/display1")
public String display1(Model model) {
model.addAttribute("name", "홍길동");
//model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
@RequestMapping("/display2")
public String display2(Model model) {
model.addAttribute("name", "임꺽정");
//model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
@RequestMapping("/display3")
public String display3(Model model) {
model.addAttribute("name", "전우치");
//model.addAttribute("now", new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date()));
return "model_display";
}
//메소드에 반환되는 객체(값)을 현재 Controller 클래스에 작성된 모든 요청 처리 메소드의 뷰에게 제공
@ModelAttribute(value = "now")
//시스템의 현재 날짜와 시간을 문자열로 반환하는 메소드
public String getNow() {
return new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(new Date());
}
}
'학원 > 복기' 카테고리의 다른 글
[Spring] Session Scope / @SessionAttributes (0) | 2023.08.08 |
---|---|
[Spring] @RequestMapping, @RequestParam, @ModelAttribute (Request) (0) | 2023.08.07 |
[Spring] MVC2 예제 (Spring) (0) | 2023.08.06 |
[Spring] MVC2 예제 (Spring X) (0) | 2023.08.06 |
[Spring] 데이터베이스 연동 (0) | 2023.08.06 |