스프링 DI WebMVC 구현 방식
📔Controller를 위한 주요 클래스
org.springframework.web.servlet.mvc.Controller
- 스프링에선 더 이상 서블릿을 상속 받지 않고, 컨트롤러 인터페이스를 활용하여 컨트롤러를 만든다.
- Controller 인터페이스를 구현하는 AbstractController 클래스를 활용하여 더 다양한 기능을 활용할 수 있다.
org.springframework.web.servlet.DispatcherServlet
- 프론트 컨트롤러를 위한 클래스이다.
-
web.xml에서 객체를 생성해준다.
<servlet> <servlet-name>app1</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>app1</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
.action으로 경로를 지정해두면 무조건 프론트 컨트롤러를 호출하게 했다.
- DispatcherServlet 클래스의 코드를 원하는 대로 조정할 수 있는 설정 파일이 제공된다.
- 설정 파일은 가급적이면 WEB-INF안에 web.xml과 같은 위치에 만들어져야 한다.
- 설정 파일의 이름은 {객체 이름}-servlet.xml로 지어주어야 한다. 위와 같이 객체를 매핑해놓은 경우, 이름은 app1-servlet.xml이 될 것이다.
-
<url-pattern>/</url-pattern>
을 입력하면 페이지가 시작할 때부터 바로 DispatcherServlet 클래스를 호출할 수 있다.# 📔 컨트롤러 생성하기
## 📝 xml 파일로 컨트롤러 설정하기
📄 app1-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean name="/spring1.action" class="webproject1.controller.SpringController"></bean> </beans>
name
속성을 통해 요청 이름을 지정해줄 수 있다. (서블릿 매핑의url-pattern
태그와 동일)
📝 컨트롤러 동작 과정
SpringController.java
package webproject1.controller;
public class SpringController extends AbstractController{
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("컨트롤러 호출됨");
return new ModelAndView("/WEB-INF/view/spring_result.jsp");
}
}
index.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<body>
<h2>Hello World!</h2>
<a href="/webproject1/hello">직접 MVC 처리</a>
<br><br>
<a href="/webproject1/spring1.action">스프링 MVC 요청 처리</a>
</body>
</html>
- spring.action 경로가 호출됨
- web.xml에서 DispatcherServlet 클래스 객체가 생성되고, 자동으로 설정 파일인 app1-servlet.xml 파일로 이동
- name 속성이 /spring1.action인 빈 객체를 찾아서 생성한다.
- 이 경우, AbstactController 클래스를 상속받는 springController 객체가 생성되고, 자동으로 오버라이딩한 메서드가 호출된다.
- 리턴 값에 명시된 경로의 페이지가 보인다.
📝 어노테이션을 통해 컨트롤러 설정하기
그냥 @Component 어노테이션을 사용하면 일반 빈 객체가 생성이 되는데, 컨트롤러 클래스를 상속받는 객체를 만들기 위해서는 @Controller 어노테이션을 사용하면 된다. 이 경우, 컨트롤러 클래스를 따로 상속 받을 필요도 없다.
SecondController.java
@Controller
public class SecondController {
@RequestMapping("/first")
protected ModelAndView firstPage() {
return new ModelAndView("/WEB-INF/view/first.jsp");
}
@RequestMapping("/second")
protected ModelAndView secondPage(HttpServletRequest req) {
String p1 = req.getParameter("p1");
String p2 = req.getParameter("p2");
ModelAndView mv = new ModelAndView("/WEB-INF/view/second.jsp");
mv.addObject("param1", p1); //request.setAttribute("param1", p1);
mv.addObject("param2", p2);
return mv;
}
//@RequestMapping(value="/third", method=RequestMethod.POST)
@PostMapping("/third")
protected ModelAndView thirdPage(String name, int age, double point) {
System.out.println(name + ", " + age + ", " + point);
return new ModelAndView("/WEB-INF/view/third.jsp");
}
}
@RequestMapping 어노테이션을 통해 해당 요청이 왔을 때, 자동으로 메서드를 실행하도록 지정해줄 수 있다. 이를 통해서 이제 서블릿을 클래스가 아닌 메서드 단위로 지정해줄 수 있다.
request 객체로 값을 처리하는 게 번거로울 수 있는데, 아예 매개변수로 값을 받아와도 된다. 여기에는 어노테이션이 생략되었는데, 원래 형태는 다음과 같다.
@PostMapping("/third")
protected ModelAndView thirdPage(@RequestParam("name") String ireum,
@RequestParam int age,
@RequestParam double point) {
System.out.println(name + ", " + age + ", " + point);
return new ModelAndView("/WEB-INF/view/third.jsp");
}
따로 지정해주지 않으면 매개변수 명과 받아오는 파라미터 명을 똑같이 일치시켜야 하지만, 어노테이션을 통해서 변수 명을 바꿔줄 수 있다.
second.jsp
<%@ page contentType="text/html; charset=UTF-8" isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>여기는 second.jsp 입니다.</h1>
param1 : <%= request.getAttribute("param1") %><br>
param2 : ${param2}<br>
</body>
</html>
maven 버전이 오래된 경우 isELIgnored 속성의 디폴트 값이 true로 되어있기 때문에 false로 다시 지정을 해주면 정상적으로 작동한다.
📝 컨트롤러에서 간단하게 값 넘겨주기
- Model addAttribute()
- ModelAndView addObject()
- @RequestParam
- @ModelAttribute
SecondController.java
@Controller
public class SecondController {
...
@RequestMapping("/fourth")
protected ModelAndView fourthPage(String name, int age, double point, Model model) {
User user = new User();
user.setName(name);
user.setAge(age);
user.setPoint(point);
ModelAndView mv = new ModelAndView("/WEB-INF/view/fourth.jsp");
model.addAttribute("user", user); //mv.addObject(user);
return mv;
}
}
📝 Model addAttribute(String attributeName, @Nullable Object attributeValue)
해당 함수를 이용해 모델 객체 변수에 넘겨주고자 하는 객체 값을 넘겨주기만 해도 해당 값을 목적지 페이지에서 활용할 수 있다.
📝 fourth.jsp
<%@ page contentType="text/html; charset=UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>여기는 fourth.jsp 입니다.</h1>
<ul>
<li>${user.name}</li>
<li>${user.age}</li>
<li>${user.point}</li>
</ul>
</body>
</html>
📝 @ModelAttribute
@GetMapping("/fourth")
public ModelAndView fourthPage(@ModelAttribute User user, @RequestParam String chk) {
ModelAndView mv = new ModelAndView("/WEB-INF/view/fourth.jsp");
mv.addObject("user", user);
mv.addObject("chk", chk);
return mv;
}
넘어오는 값들이 user Dto 클래스의 프로퍼티들과 맞아떨어지면 해당 어노테이션을 통해 자동으로 값을 받아올 수 있다. 이 어노테이션은 생략이 가능하다. 넘어오는 값들과 Dto 클래스의 프로퍼티들이 맞아떨어지지 않는다면, 그 파라미터들은 그냥 @RequestParam을 통해 받아와주면 된다.
📝 매개변수로 ModelAndView값 받아오기
@GetMapping("/fifth")
public ModelAndView fifthPage(ModelAndView mv) {
List list = new ArrayList();
list.add("김치찌개");
list.add("삼겹살");
list.add("치킨");
list.add("국밥");
mv.setViewName("/WEB-INF/view/fifth.jsp");
mv.addObject("foods", list);
return mv;
}
이런 식으로 매개변수에서 ModelAndView 객체를 가져올 수도 있다. Model과 ModelAndView 클래스를 매개변수로 정해주는 모습을 볼 수 있는데, 어디선가 객체를 생성해서 값을 받아오는 것이라 아니라, 빈 객체를 받아오는 것 또는 파라미터 자리에서 객체를 생성했다고 받아들이면 더 익숙하게 활용할 수 있을듯하다.
댓글남기기