게시판〃(6) Controller 패키지 작성

반응형


이번글에서는 게시판 프로젝트중에 가장 중요한 부분인 컨트롤러 부분에 대해 만들어 보겠습니다.다시 복습겸 MVC패턴과 게시판 순서를 되짚어보면 웹컨테이너에서 디스패쳐 서블릿으로 해당정보를 요청합니다. 


그걸 web.xml에서 디스패쳐 서블릿 설정을 하고 URL매핑을 합니다. 저는 <url-pattern> *.action </url-pattern>으로 설정해주었고요. 다음 <servlet-name>을 board로 지었기에 board-servlet.xml에서 핸들러매핑으로 받아 컨트롤러로 향하도록 정해줍니다.


board-servlet.xml에서 리스트를 예로 들면 <prop key="/boardList.action"> listController </prop>소스코드가 있습니다. 그 의미는 자바파일 중 ListController의 이름으로 된것에 연결하고 그 안에 /boardList.action의 정보가 들어가 있을 것이죠. 




그 절차에 해당하는 컨트롤러를 지금 만들 예정이고, 제목 (5)번에서 작성에 필요한 DTO와 DAO 즉, 데이타를 먼저 만들어 주었습니다. 그래서 이번 제목 (6)번에서는 컨트롤러를 만들 차례입니다. 방금까지 해당되는 절차에 도움되는 글은 링크를 통해 보고 오시면 이해가 빠릅니다.

 



ListController.java 작성하기



먼저 board.controller라는 이름으로 패키지를 하나 생성해줘야죠. 그 안에 모든 컨트롤러에 해당하는 자바파일을 전부 담을 것입니다. 이렇게 기능을 나눠 놓으니 정말 한눈에 보기 편하네요. 사진을 보시면 Ajax기능도 추가할 예정이라 AjaxController 파일도 보입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package board.controller;
 
import java.util.List;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
 
import board.dao.BoardDaoImpl;
import board.dto.BoardDto;
import board.dto.PageDto;
import board.service.BoardService;
 
@Controller
public class ListController {
    @Resource(name="boardService")
    private BoardService boardService;
 
    /*  서비스 주입이 잘되는지 테스트하는 코드
    public void setBoardService(BoardService boardService){
        System.out.println(boardService + " 서비스 주입 확인");
        this.boardService = boardService;
    } */
    
    @RequestMapping(value="/boardList.action")
    public ModelAndView list(@RequestParam(required=false) Integer nowPage,@RequestParam(required=false)Integer nowBlock,
            @RequestParam(required=falseString keyField, @RequestParam(required=falseString keyWord)
    {
        ModelAndView view = new ModelAndView();
        List<BoardDto> list = boardService.boardList(keyField, keyWord);
        PageDto page = null;
        try{
            page = boardService.pagingProc(nowPage, nowBlock, list.size());
        }
        catch(Exception err){
            System.out.println("now페이지와 now블럭이 존재하지 않아 0을 대입했습니다.");
            System.out.println("에러내용은 다음과 같습니다." + err);
            page = boardService.pagingProc(00, list.size());
        }
        
        view.addObject("dao"new BoardDaoImpl());
        view.addObject("list", list);
        view.addObject("page",page);
        view.addObject("keyWord",keyWord);
        view.addObject("keyField",keyField);
        view.setViewName("Board_List");
        
        return view;
    }
}


ListContorller.java 소스코드


이 클래스가 컨트롤러 부분이다라고 어노테이션으로 ListController 위에 선언하고 코드를 작성하기 시작합니다. 그리고 저번글에서 작성했던 boardServiceImpl.java기능이 들어간 boardService.java를 @Resource로 자동연결합니다.


다음 @RequestMapping으로 컨트롤러가 처리할 요청 URL("valure="boardList.action")을 명시하고, 아래 모델앤뷰클래스에서 list를 로직 처리하고 리턴구문을 작성하여 [51번째]줄에서 view를 리턴하게 됩니다. 이 어노테이션의 장점은 다수의 메소드에 적용할시 하나의 장소에서 한번에 처리할수 있죠. 자세하게는 따로 정리해서 링크를 올리도록 하겠습니다.


모델앤뷰 클래스를 살펴보면 예외구문을 만들어 list가 잘 동작되나 확인하기 위한 코드를 작성하였고, 아래 view.addObjet는 화면에 표시될 Jsp파일에게 넘겨줄 값을 addObject 메소드로 정의한 것입니다. 마지막 view.setViewName 메소드로는 jsp 페이지를 지정하죠.


여기서 놓치면 안되는 재밌는 부분은 view.addObject로 지정한 메소드 dao / list / page 들 제 파일중 View의 역활을 하는 Board_list.jsp 에서 ${dao} / ${page} 로 사용할 수 있게 됩니다.





 WriteController.java 작성하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package board.controller;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
import board.dto.BoardDto;
import board.service.BoardService;
 
@Controller
public class WriteController {
 
    @Resource(name="boardService")
    private BoardService boardService;
    
    @RequestMapping(value="/boardWrite.action", method=RequestMethod.GET)
    public String wirteView(){
        return "Board_Write";
    }
    
    @RequestMapping(value="/boardWrite.action", method=RequestMethod.POST)
    public String insert(@ModelAttribute BoardDto dto){
        String content = dto.getContent();
        String content2 = content.replace("\n""<br/>");
        dto.setContent(content2);
        boardService.insertBoard(dto);
        return "redirect:boardList.action";
    }
}


▲ WriteContorller.java 소스코드

게시판 리스트를 봤으면 이젠 글을 써봐야겠죠. 게시판 글쓰기 코드는 의외로 간단하죠?? 여기서는 중복되는 어노테이션들에 대한 설명은 생략하도록 하겠습니다. 


[19번째]과 [24번째] 줄을 보시면 @RequestMapping 메소드 전송방식이 GET방식과 POST방식이 나눠져 있습니다. 이건 ① GET방식은 글을 작성할때 ② POST방식은 글을 작성하고 리스트로 넘어갈때 나눠서 컨트롤러를 작성한 것입니다. 


간단하게 설명하자면 POST방식은 정보를 처리할때 사용하는 용도로 글쓰고 나서 데이타를 list.action으로 보내기 위한 방식으로 사용하였고, GET방식은 정보를 가져와 보여주는 용도이므로 글쓰기를 할때 사용하였습니다. 아참..마지막 [30번째]줄의 "redirect"는 바로 전송한다고 생각하시면 될거에요.





 ViewController.java 작성하기



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package board.controller;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
 
import board.dto.BoardDto;
import board.service.BoardService;
 
@Controller
public class ViewController {
    @Resource(name="boardService")
    
    private BoardService boardService;
    
    @RequestMapping(value="/boardView.action", method=RequestMethod.POST)
    public ModelAndView read(@RequestParam int seq, String keyField, String keyWord)
    {
        ModelAndView view = new ModelAndView();
        view.setViewName("Board_View");
        BoardDto dto = boardService.viewContent(seq);
        view.addObject("dto",dto);
        view.addObject("keyField",keyField);
        view.addObject("keyWord",keyWord);
        return view;        
    }
 
}


▲ ViewContorller.java 소스코드


이제 글을 썼으면 다음 단계인 게시글을 열람하는 코드입니다. 메소드 전송방식은 POST방식으로 전달하게 했고 JSP페이지로는 Board_View.jsp로 전달됩니다. 그 페이지에서는 ${dto}, ${keyField}, ${keyWord}를 사용할 수 있겠네요.





 UpdateController.java 작성하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package board.controller;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
 
import board.dto.BoardDto;
import board.service.BoardService;
 
@Controller
public class UpdateController {
    @Resource(name="boardService")
    private BoardService boardService;
    
    @RequestMapping(value="boardUpdate.action",method=RequestMethod.GET)
    public ModelAndView updateView(@RequestParam int seq){
        ModelAndView view = new ModelAndView();
        System.out.println(seq);
        BoardDto dto = boardService.findBySeq(seq);
        view.addObject("dto",dto);
        view.setViewName("Board_Update");
        return view;        
    }
 
    @RequestMapping(value="boardUpdate.action", method=RequestMethod.POST)
    public ModelAndView updateView(@ModelAttribute BoardDto board,@RequestParam String pass)
    {
        ModelAndView view = new ModelAndView();
        int result = boardService.updateBoard(board, pass);
        
        if(result == 1){
            System.out.println("수정 완료");
            view.setViewName("redirect:boardList.action");
        }else{
            System.out.println("수정 실패 이유 :" + result);
            view.addObject("result",result);
            view.setViewName("redirect:boardUpdate.action?seq="+board.getSeq());;
        }return view;
    }
}


▲ UpdateContorller.java 소스코드


다음은 글을 수정하는 UpdateController의 코드입니다. 리스트와 글읽기, 글쓰기를 작성해보니 글수정하는 코드도 이제 적응이 많이 됬습니다. 여기서 보셔야 될건 [31번째]줄의 @ModelAttribute 이며 사용한 이유는 key값과 value값을 객체 형식으로 쓰기 위한 어노테이션입니다. 


[34번째]줄에서 result값을 boardService.updateBoard (board, pass)로 담기 위해 쓴것이죠. 사실 생략해도 되는 어노테이션이지만 여려가지 공부를 위해 적었습니다. 한가지 더하자면 @ModelAttribute는 오브젝트나 DTO의 프로퍼티에 담긴 파라미터를 한번에 받기 위해 사용되고, @RequestParam은 요청 파라미터를 메소드 파라미터에서 일대일로 받기위해 사용됩니다. 그리고 if문을 통해 패스워드값이 들어오면 수정이 완료가 되고, else에서는 실패하면 행동해야할 코드입니다.





 DeleteController.java 작성하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package board.controller;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
 
import board.service.BoardService;
 
@Controller
public class DeleteController {
    @Resource(name="boardService")
    
    private BoardService boardService;
    
    @RequestMapping(value="/boardDelete.action", method=RequestMethod.GET)
    public ModelAndView deleteView(@RequestParam int seq){
        ModelAndView view = new ModelAndView();
        view.setViewName("Board_Delete");
        
        String storPass = boardService.deleteView(seq);
        Map map = new HashMap();
        map.put("seq",seq);
        map.put("storPass", storPass);
        view.addAllObjects(map);
        return view;
    }
    
    @RequestMapping(value="boardDelete.action",method=RequestMethod.POST)
    public ModelAndView delete(@RequestParam int seq, @RequestParam String storPass){
        ModelAndView view = new ModelAndView();
        int result = boardService.deleteBoard(seq, storPass);
        System.out.println("딜레트의 결과값은 : " + result);
        if(result == 1){
            System.out.println("삭제에 성공하였습니다.");
            view.setViewName("redirect:boardList.action");
        }else{
            System.out.println("삭제에 실패하였습니다.");
            view.setViewName("redirect:boardDelete.action?seq="+ seq);
            view.addObject("result",result);
        } return view;
    }
 
}


▲ DeleteContorller.java 소스코드


Delete컨트롤러는 HashMap을 이용해서 삭제화면을 만들었습니다. HashMap은 Map인터페이스로 Map의 속성과 저장방식이 동일하며 Hasing의 검색방법을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어 뛰어난 성능을 가지고 있습니다. 


그 부분이 [28~31]에 해당하는 부분이고 map.put으로 ( key , value )값을 저장합니다. addAllObjects(map)은 map에 저장된 key와 value값 전체를 view에 전달하겠다는 기능를 가지고 있습니다.


참고로 [22~33]은 삭제를 하기위해 비밀번호를 입력하라는 화면에서 쓰이는 기능, [35~48]은 삭제에 성공하는지, 실패하는지의 정보를 처리하는 기능입니다.




 ReplyController.java 작성하기



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package board.controller;
 
import javax.annotation.Resource;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
 
import board.dto.BoardDto;
import board.service.BoardService;
 
@Controller
public class ReplyController {
    @Resource(name="boardService")
    private BoardService boardService;
    
    
    @RequestMapping(value="/boardReply.action",method=RequestMethod.GET)
    public ModelAndView read(@RequestParam int seq){
        ModelAndView view = new ModelAndView();
        BoardDto dto = boardService.findBySeq(seq);
        view.addObject("dto",dto);
        view.setViewName("Board_Reply");
        return view;
    }
    
    //답변작성후 Board_List로 돌아가는 컨트롤러
    // 부모의 dto = board
    @RequestMapping(value="/boardReply.action",method=RequestMethod.POST)
    public String read(@ModelAttribute BoardDto dto,@RequestParam int temp_seq){
        ModelAndView view =new ModelAndView();
        view.setViewName("Board_List");
        
        BoardDto board = boardService.findBySeq(temp_seq);
        boardService.replyUpPos(board);
        dto.setPos(board.getPos());
        dto.setDepth(board.getDepth());
        System.out.println("원본 Pos" + board.getPos());
        String content = dto.getContent();
        String content2 = content.replace("\n""<br/>");
        dto.setContent(content2);
        boardService.replyBoard(dto);
        
        return "redirect:boardList.action";
    }
}


▲ ReplyContorller.java 소스코드

이제 답변을 하는 컨트롤러로 거의 끝나가네요. 이제 왠만한 코드들은 위에서 다 언급해서 몇가지만 언급하면 끝이 날 것 같습니다. [21~28]은 답변을 작성하는 화면 , [32~48]은 답변을 완료하면 원래 글 밑에 답변이 달리게 하는 기능을 담고 있습니다. 


여기서 정리할 부분은 [33~40]에 board와 dto가 동시에 같이 쓰인것이네요. 글로 설명하기에는 정말 어렵고, 이해하기도 힘들겠지만 한번 적어보겠습니다. [33번째]줄에서 @ModelAttribute로 BoardDto의 파라미터를 한번에 전달받은것은 dto이고, [37번째]줄에서 BoardService의 findBySeq메소드로 temp_seq값을 저장받은것은 board입니다. 


둘다 boardDto의 데이터를 사용하고 dto > board 의 크기를 가지고 있습니다. 그래서 저장받은 시퀀스의값 temp_seq를 board가 가지고 [39번째]줄에서 dto.setPos (board. getPos())코드로 pos의 값을 설정했습니다.  




 AjaxController.java 작성하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package board.controller;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import board.mybatis.BoardManager;
import board.service.BoardService;
 
@Controller
public class AjaxController {
    @Resource(name="boardService")
    private BoardService boardService;
    
    @RequestMapping(value="/boardAjax.action")
    public void ajaxlist(HttpServletRequest req, HttpServletResponse res) 
            throws IOException{
        int seq = Integer.parseInt(req.getParameter("seq"));
        req.setCharacterEncoding("utf-8");
        res.setContentType("text/html; charset=utf-8");
        res.setHeader("Cache-Control""no-cache");
        
        String preContent = BoardManager.preView(seq);
        PrintWriter out =res.getWriter();
        out.print(preContent);
    }
}


▲ AjaxContorller.java 소스코드


휴.. 마지막 Ajax를 컨트롤하는 부분인데요. 아직 Ajax 카테고리에 이론을 정리해놓은 부분이 없어 조만간 링크를 걸도록 하겠습니다. 아마도 제 계획에는 글의 길이가 너무 길어서 Ajax컨트롤러는 따로 적을까 생각도 하고있어요. 


추가 ++)) 아래 링크


반응형