IT_Programming/Dev Libs & Framework

[펌] Spring Controllers

JJun ™ 2013. 4. 5. 18:01


 출처: http://javastore.tistory.com/


 

 

 

1.AbastractCommandController

 

 

[소개]
AbstractCommandController는 페이지의 넘어오는 파라미터들을 bean 객체에 자동맵핑이 되어

Controller 에서 사용 할 수 있게 만드는 역할을 한다. 즉, jsp 페이지의 회원가입페이지 에서

파라미터로 name,age... 등등이 넘어오면 선언한 bean의 property인 String name, String age에 대응되어

자동 저장이 된다.

[사용방법]
DI를 선언한 xml 파일에서 직접 bean의 클래스경로인 "commandClass" 와 commandClass의 이름인

"commandName" 을 파라미터로 넘겨주어야 한다.

 

 예)
< bean id="listAbstractCommandController"
       class="kr.co.springboard.controllers.ListAbstractCommandController">

     <property name="commandClass" value="kr.co.springboard.beans.BoardBean"/>
     <property name="commandName" value="boardBean"/>

     <property name="boardService" ref="boardService"/>
     <property name="viewName" value="boardList"/>
< /bean>

 


이렇게 property 로 설정하는 방법이 있는가 하면 직접 AbstractCommandController를 확장한 클래스에서 다음과 같이 Contructor를 구현해도 된다.

 

public ListAbstractCommandController(){
     setCommandClass(BoardBean.class);
     setCommandName("boardBean");
 }
 


위의 2가지 방법으로 선언하면 AbstractCommandController의 handle() method를 통해서 전달 인자인 command를 통해 전송된 데이터를 받을 수 있다.

 

 protected ModelAndView handle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object command,
                         BindException errors) throws Exception {
  ModelAndView mnv = new ModelAndView();
  BoardBean boardBean = (BoardBean)command;
  BoardDTO dto = new BoardDTO();
  dto.setNowPage(boardBean.getNowPage());
  
  if(dto.getNowPage() == 0){
   dto.setNowPage(1);
  }
  dto.setTotalCount(boardService.boardTotalCount(dto));
  dto = (BoardDTO)PagingUtil.setPagingInfo(dto);
  List<BoardDTO> boardList = this.boardService.boardList(dto);
  
  mnv.setViewName(viewName);
  mnv.addObject("boardList", boardList);
  mnv.addObject("dto",dto);
  
  return mnv;
 }

 

 

위와 같이 생성자,혹은 xml문서의 property 로 세팅해준 commandClass와 commandName 은 handle() 메소드의 command object를 통해 데이터를 전달 받기 때문에 command instance를 생성해 주는 역할을 한다. 이렇게 전달된 command 객체를 원하는 형으로 형변환을 해서 사용하면 된다.

 

 

 


 

 

 

 

 

2.SimpleFormController

 

[역할]
Controller의 이름에서도 알수 있다 시피 SimpleFormController는 입력받는 Form을 간단하게

만들어 줄수 있는 Controller 이다. 즉, 입력과 수정창, 예를 들면 게시판의 글쓰기와 글 수정 창을

따로따로 만들 필요 없이 http get 으로 들어오면 글쓰기 창을 보여주고 글 정보를 쓸 때(글쓰기,글 수정)

http post 방식으로 들어올때는 글을 디비에 입력하는 이런 따로따로인 기능을 하나의 클래스로

구현하는 것이다. 그렇기 때문에 수정form과 입력form을 두가지 따로따로 만들 필요가 없는 것이다.

[사용방법]
SimpleFormController를 사용하기 위해서는 이 클래스를 상속 받아서 써야 한다.

SimpleFormController를 사용하게 되면 formBackingObject() method와 onSubmit() 메소드를

overriding 해서 사용할 수 있다.

게시판에서 예를 들어 보면 게시판에 글을 쓰는 폼을 보여주거나, 게시판의 글을 수정하는 폼을

보여주는 것을 simpleFormController로 구현한다고 하자. 글쓰기나 수정 둘다 form을 요청할 때는

get 방식을 사용할 것이다.(왜냐 하면 URL을 통해 form에 접근하기 때문이다)

그리고 사용자로 부터 글을 쓴 정보, 혹은 수정한 정보들은 post 방식으로 컨트롤러에 접근할 것이다.

이 때 formBackingObject() method 는 get방식으로 접근할때 실행 되고 onSubmit() method는

post방식으로 데이터가 넘어올때 실행이 된다.

 

그림으로 보면


 


다음과 같은 실행 루틴을 거친다.

1. 사용할 클래스에 SimpleFormController를 상속 받아 formBackingObject() 와 onSubmit()를

    override 한다.

 
package kr.co.springboard.controllers;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.co.springboard.dto.BoardDTO;
import kr.co.springboard.service.BoardService;

import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

public class WriteSimpleFormController extends SimpleFormController {
    private BoardService boardService;
    public void setBoardService(BoardService boardService) {
        this.boardService = boardService;
    }

   
   
    @Override
    protected Object formBackingObject(HttpServletRequest request)
                                       throws Exception {
        int seq = ServletRequestUtils.getIntParameter(request, "seq", 0);
        BoardDTO boardDto = null;
        if(seq == 0){
            boardDto = new BoardDTO();
        }else if(seq > 0){
            boardDto = this.boardService.boardRead(seq);
        }
        return boardDto;
    }



    @Override
    protected ModelAndView onSubmit(HttpServletRequest request,
                                    HttpServletResponse response,
                                    Object command, BindException errors)
                                    throws Exception {
        ModelAndView mnv = new ModelAndView();
        BoardDTO dto = (BoardDTO)command;
        if(dto.getSeq() == 0){
            boardService.boardInsert(dto);
        }else{
            boardService.boardUpdate(dto);
           
        }
        mnv.setViewName(getSuccessView());
       
        return mnv;
    }
   
}



 2. DI설정부분에서 formView,successView,commandClass,commandName을 property로 설정한다.

 

< bean id="writeSimpleFormController" class="kr.co.springboard.controllers.WriteSimpleFormController">
        <property name="commandClass" value="kr.co.springboard.dto.BoardDTO"/>
        <property name="commandName" value="boardDto"/>
        <property name="formView" value="writeForm"/>
        <property name="successView" value="writeSuccess"/>
        <property name="boardService" ref="boardService"/>
< /bean>


기본적으로 onSubmit()을 실행할때는 AbstractCommandController에서 command 객체를 통해 입력된

정보를 받아오는데 SimpleFormController의 onSubmit()도 이와 같은 방식을 채택하고 있다.
그렇기 때문에 commandClass와commandName을 통해 command객체를 생성해 준다.

 

 또하나 아주 중요한 역할은 formBackingObject에서 boardDto를 리턴해 주는데 commandName에 설정한 이름으로 request 객체에 담기기 때문에 commandName을 세팅해 주지 않으면 절대로 form 페이지에서 정보를 받을 수가 없다.

 

그리고 formView는 formBackingObject를 실행되었을때 자동적으로 ModelAndView 객체에 세팅이 됨으로 따로 세팅해주어야 할 필요는 없다. successView는 성공하고 보여질 페이지를 세팅한다. SimpleFormController 안에 있는 getSuccessView method를 통해 값을 가져 올 수 있다.

 

 


 

 

 

3.MultiActionController

 

 

 

[역할]
MultiActionController는 하나의 Controller 클래스에서 여러 가지 기능을 하는 method를 구현해 놓고

파라미터 값으로 넘어오는 어떠한 값과 MultiActionController에 구현한 method와의 이름을 비교해서

실행을 시킨다.


이 MultiActionContorller는 주로 비슷한 기능을 가진 method끼리 모아 쓸데 없이 클래스를 많이 생성해서

생길수 있는 class overhead를 줄여주는 방법이다.

[적용방법]
1. 일단 구현할 클래스를 MultiActionController를 확장해서 구현한다. method는 overriding을 할 필요 없고

    사용자가 원하는 이름으로 구현하면 된다. 보통 리턴값은 ModelAndView로 리턴값을 정하지만

    다른 Map,String,void를 선택적으로 사용할 수 있다.

    그리고 전달 parameter들은 HttpServletRequest,HttpServletResponse를 사용한다.

   

 예)

protected ModelAndView read(HttpServletRequest request,HttpServletResponse response);

package kr.co.springboard.controllers;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.co.springboard.dto.BoardDTO;
import kr.co.springboard.service.BoardService;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class ReadDeleteMultiActionController extends MultiActionController{
    private BoardService boardService;
    public void setBoardService(BoardService boardService) {
        this.boardService = boardService;
    }

    public ModelAndView boardRead(HttpServletRequest request,
                                  HttpServletResponse response){
        ModelAndView mnv = new ModelAndView();
        int seq = Integer.valueOf(request.getParameter("seq"));
        this.boardService.boardUpdateReadCount(seq);
        BoardDTO boardDto = this.boardService.boardRead(seq);
        mnv.addObject("boardDto",boardDto);
        mnv.setViewName("boardRead");
        return mnv;
       
    }
   
    public ModelAndView boardDelete(HttpServletRequest request,
                                    HttpServletResponse response){
        ModelAndView mnv = new ModelAndView();
        int seq = Integer.valueOf(request.getParameter("seq"));
        this.boardService.boardDelete(seq);
        mnv.setViewName("boardDeleteSuccess");
        return mnv;
    }
}

 


2.DI를 구현한 부분에 ParameterMethodNameResolver 를 구현하고 이것을 통해서 DI를 설정한다.

 

 

 < bean id="readDeleteMultiActionController"
          class="kr.co.springboard.controllers.ReadDeleteMultiActionController"
          p:boardService-ref="boardService"
          p:methodNameResolver-ref="boardReadDeleteNameResolver"/>

 

 


<bean id="boardReadDeleteNameResolver"
          class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
     <property name="paramName" value="mode"/>
< /bean>

 


이렇게 세팅해 주면 된다. 이렇게 세팅하면 주소창에

 http://localhost/springboard/board.do?mode=

이렇게 입력한 뒤에 mode뒤에 자기가 실행하고 싶은 method를 입력하면 된다.

 

클래스의 boardRead ()를 실행하고 싶으면 mode=boardRead, boardDelete를 실행하고 싶으면

  mode=boardDelete

를 실행 하면 된다.

 

mode는 ParameterMethodNameResolver에서 property로 선언한 paramName에서 세팅한 것과

동일한 것이어야 한다.