Spring/Spring

day65) Spring-Controller 설계2:DispatcherServlet-servlet.xml @로 변경하기

code_learner 2022. 4. 4. 02:13

이전 내용: https://code-learning.tistory.com/107

 

day64) Spring-Controller설계

Spring에서 제공하는 DispatcherServlet과 스프링 컨테이너를 활용하여 Controller를 설계해보자. [설계] NewFile.jsp에서 글을 쓰면 /WEB-INF/NewFile1.jsp(url로 접근할 수 없도록)에서 출력 [View] NewFile.jsp..

code-learning.tistory.com

 

위 게시글에서 DispatcherServlet-servlet.xml을 살펴보면 ViewResolver클래스를 호출하여 prefix와 suffix를 set해주는 과정, HandlerMapping클래스 호출하여 *.do action과 해당 클래스를 매핑하는 구문으로 이루어져 action이 많아질 수록 설정이 많아지는 것을 볼 수 있다.

더보기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- DS를 위한 스프링 컨테이너를 위한 설정파일. init()이 자동호출될적에 필요 -->
	<!-- DS 생성 -> init() 자동호출 -> DI -> 컨테이너가 하는 일 -> 설정파일(.xml) -> DS-servlet.xml -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
		<!-- id를 써줄 것: 1. ~Resolver를 많이 써서 내부적으로 viewResolver를 쓸 수 있도록 설정해둠 -->
		<!-- viewResolver를 통해 간다면 WEB-INF 경로도 접근가능해진다 -->
		<property name="prefix" value="/WEB-INF/view/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	<!-- redirect: 가 붙지 않은 viewName을 보면, DS는 Mav객체에서 M정보를 추출, req객체에서 M정보를 저장해서 JSP포워딩 -->

	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/insert.do">next</prop>
			</props>
		</property>
	</bean>
	<bean class="com.test.app.controller.board..insertBoardController" id="insertBoard"></bean>

</beans>

이러한 점을 보완하기 위해 어노테이션을 사용하여 설정파일을 가볍게 하고자 한다.

 


[방법]

HandlerMapping과 ViewResolver는 SpringFramework가 제공하는 기능이므로 구현할 필요가 없다.

 

1.DispatcherServlet-servlet.xml에서 Namespaces -> context추가

2. component-scan을 통해 controller 클래스를 볼수 있도록 설정

<context:component-scan base-package="(controller패키지 경로)"/>

 

3.~controller 클래스 변경

-기존 insertBoardController.java

더보기
public class InsertBoardController implements Controller {
	@Override
   		public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
      		String content=request.getParameter("content");
      		String title=request.getParameter("title");
     		String writer=request.getParameter("writer");
      		BoardVO vo=new BoardVO();
          	vo.setContent(content);
      		vo.setTitle(title);
      		vo.setWriter(writer);
      		BoardDAO boardDAO=new BoardDAO();
     		boardDAO.insertBoard(vo);
     	 	ModelAndView mav=new ModelAndView();
     	 	mav.setViewName("redirect:main.do");
     	 	return mav;
   	}
   }

 

3-1. @Controller 어노테이션 추가

- DispatcherServlet-servlet.xml에서 <bean>으로 ~Controller클래스 객체를 생성, 매핑파여 처리하던 부분을 @controller를 통해 처리한다.

- implements Controller가 필요없어지므로 삭제

- 메서드 강제가 없어져 Controller 인터페이스도 쓸모가 없어지므로 삭제

완전한 POJO가 되었다!!!!!
  -> req,res,...가 존재하지않음 => 경량의 객체

3-2. /insertBoard.do 요청에대해 insertBoard()메서드가 수행되어야한다.
- @RequestMapping(value="/insertBoard.do")

 

ver1

더보기
@Controller
public class InsertBoardController {

   @RequestMapping(value="/insertBoard.do")
   public void insertBoard(HttpServletRequest request) {
      String content=request.getParameter("content");
      String title=request.getParameter("title");
      String writer=request.getParameter("writer");
      BoardVO vo=new BoardVO();
      vo.setContent(content);
      vo.setTitle(title);
      vo.setWriter(writer);
      BoardDAO boardDAO=new BoardDAO();
      boardDAO.insertBoard(vo);
   }
  }

 

3-3. Command객체 사용

기존에는 req를 통해 받아온 파라미터들을 하나하나 vo에 set해야 했지만 스프링이 제공하는 커맨드 객체를 사용하면 일련의 과정을 줄일 수 있다.

- 인자를 request에서 VO로 바꾼다

- VO 객체 생성

- VO의 setter 자동호출, 추출한 값을 매핑 저장
      == VO에 setter주입

 

ver2

더보기
@Controller
public class InsertBoardController {
   @RequestMapping(value="/insertBoard.do")
   public void insertBoard(BoardVO vo,BoardDAO boardDAO) {
      boardDAO.insertBoard(vo);
   }
  }

 

3-4.  return값 void -> String -> ModelAndView

-return할 페이지에 전달할 값이 없다면 String을 통해 경로만 지정하면된다

 (ViewResolver가 인식할 수 있도록 "redirect: ~"를 붙이자

-ViewResolver에서 인식하는 디폴트 전달방식이 forward방식이므로 전달할 값이 있다면 .addObject메서드를 통해 값을 저장하고 .setViewName메서드에 해당 경로만 지정해주면 된다.

 

ver3

더보기
@Controller
public class InsertBoardController {
   @RequestMapping(value="/insertBoard.do")
   public ModelAndView insertBoard(BoardVO vo,BoardDAO boardDAO,ModelAndView mav) {
      boardDAO.insertBoard(vo);
      mav.setViewName("redirect:main.do");
      return mav;
   }
  }

 

3-5. 각자 다른 action에 따른 controller객체를 호출하게 된다면 singleton패턴에 어긋나므로 하나의 클래스 내부에 @controller를 통해 모든 .do 행동에 생성되고, 각각의 @RequestMapping을 통해 해당 메서드를 찾아갈 수 있도록한다.

package com.test.app.controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.test.app.board.BoardVO;
import com.test.app.board.impl.BoardDAO;

@Controller 
public class BoardController {
	// 1. Controller 교체
	// 2. 반환타입의 변경 -> ModelAndView(무엇을 보낼지_정보_datas,data,member,... + 어디로 가야하는지_경로)

	@RequestMapping(value="/main.do")
	public ModelAndView getBoardList(BoardVO vo,BoardDAO boardDAO,ModelAndView mav) {
		// 검색 로직 추가할 예정
		List<BoardVO> datas=boardDAO.getBoardList(vo);
		mav.addObject("datas", datas); // Model을 이용하여 전달할 정보를 저장!
		mav.setViewName("main.jsp");
		return mav;
	}
	@RequestMapping(value="/board.do")
	public ModelAndView getBoard(BoardVO vo,BoardDAO boardDAO,ModelAndView mav) {
		vo=boardDAO.getBoard(vo);
		mav.addObject("data", vo);
		mav.setViewName("board.jsp");
		return mav;
	}
	@RequestMapping(value="/insertBoard.do")
	public String insertBoard(BoardVO vo,BoardDAO boardDAO) {
		boardDAO.insertBoard(vo);
		return "redirect:main.do";
	}
	@RequestMapping(value="/deleteBoard.do")
	public String deleteBoard(BoardVO vo,BoardDAO boardDAO) {
		boardDAO.deleteBoard(vo);
		return "redirect:main.do";
	}
	@RequestMapping(value="/updateBoard.do")
	public String updateBoard(BoardVO vo,BoardDAO boardDAO) {
		boardDAO.updateBoard(vo);
		return "redirect:main.do";
	}
}