3 분 소요

📔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>
  1. spring.action 경로가 호출됨
  2. web.xml에서 DispatcherServlet 클래스 객체가 생성되고, 자동으로 설정 파일인 app1-servlet.xml 파일로 이동
  3. name 속성이 /spring1.action인 빈 객체를 찾아서 생성한다.
  4. 이 경우, AbstactController 클래스를 상속받는 springController 객체가 생성되고, 자동으로 오버라이딩한 메서드가 호출된다.
  5. 리턴 값에 명시된 경로의 페이지가 보인다.

📝 어노테이션을 통해 컨트롤러 설정하기

그냥 @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 클래스를 매개변수로 정해주는 모습을 볼 수 있는데, 어디선가 객체를 생성해서 값을 받아오는 것이라 아니라, 빈 객체를 받아오는 것 또는 파라미터 자리에서 객체를 생성했다고 받아들이면 더 익숙하게 활용할 수 있을듯하다.

댓글남기기