티스토리 뷰

안녕하세요. MIN-IT입니다.


이번시간은 이어서 Spring MVC프로젝트를 이용하여 게시판을 만들어보겠습니다.


Controller와 View부분을 만들어 게시판 완성을 시켜보겠습니다.

(http://min-it.tistory.com/10 실습 후 진행해주세요)


가장 기본적인 CRUD를 배우는 시간을 가지겠습니다.


퍼가실 때 댓글을 남겨주세요!


http://min-it.tistory.com



만드신 컨트롤러 패키지에 BoardController를 생성하여 다음과 같이 입력해주세요

(Controller-BoardController)



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
package org.hello.controller;
 
import javax.inject.Inject;
 
import org.hello.domain.BoardVO;
import org.hello.service.BoardService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
@RequestMapping("/board/") //url요청이  /board/로 시작하는 것은 여기서 처리한다. ex) board/abc , board/123 board/create
public class BoardController {
    
    @Inject
    private BoardService service;
    
    @RequestMapping(value="/create",method=RequestMethod.GET)
    public void createGET(BoardVO board, Model model) throws Exception{
        System.out.println(" /board/create 입니다. GET방식");
        
    }
    
    @RequestMapping(value = "/create",method=RequestMethod.POST )
    public String createPOST(BoardVO board, Model model) throws Exception{
        System.out.println("/board/create POST방식 입니다.");
        System.out.println(board.toString());
        
        service.create(board);
        model.addAttribute("result""성공");
        
        return "/board/succes";
    }
    
    
    
    
 
}
 
cs

(BoardController)


1.클래스 위의 @RequestMapping("/board/")

-http://localhost:8081/board/로 시작되는 요청을 다 boardController에서

받겠다는 의미 입니다.

따라서 여기에있는 /create 경로를 호출하고싶다면

http://localhost:8081/board/create를 입력하세요

(만약 클래스 위에 @RequestMapping("/board/") 하지 않으셨다면

메소드들의 @RequestMapping에 일일이 board를 입력해줘여됩니다.

ex) @RequestMapping("/board/create")


2.method=RequestMethod.GET(POST)

-Rest 방식중에서 GET/POST/PUT/DELETE를 설정하는 것으로

위에서는 /create라는 경로가 2개이지만 GET인지 POST인지에 따라 호출되는

메소드가 달라집니다.


간단히 GET/POST방식의 차이점을 이야기 해드리자면


GET은 URL에 정보를 넣고 보내 원하는 자료를 요청하는 것으로

URL에 해당하는 자료의 전송을 요청하는 것이고

POST는 <body>에 숨겨서 보내는 것으로

서버가 처리할 수 있는 자료를 보내는 것입니다.

따라서  회원정보와 같이 민감한 정보들은 url(주소창)에 보여지면 안되기 때문에

POST로 전송처리를 하는것이 일반적입니다.

(대게 GET과 POST만으로 수정/삭제 처리가 가능하기때문에

PUT(수정)/DELETE(삭제)보다 중요합니다.)



3.Model

-Model이라는 클래스는 스프링 MVC에서 제공하는 데이터를 전달해주는 객체입니다.

Servlet을 공부하셨더라면 RequstDispatcher에 데이터를 저장하는 것과 같은 의미입니다.

즉, 알기쉽게 이야기하자면

model.addAttribute("result""성공"); Model은 Map처럼 ket/value형태를 가지고 있고

return "/board/succes"; 이런게 리턴되는 곳 = succes.jsp 으로

데이터가 전달됩니다.

succes.jsp에서 ${result} 입력하게되면 "성공"이라는 문구가 뜨는겁니다.

(화면에 데이터를 뿌려주기위해 사용하는것 중 하나가 Model클래스라고 이해하세요)








그다음

viesw폴더에서 board라는 하위폴더를 생성하고 create.jsp와 succes.jsp를 만들고

다음과 같이 입력합니다.



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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page session="false" %>
<html>
<head>
    <title>게시판</title>
</head>
<body>
<h1>
    게시판 등록하기  
</h1>
    
    <form action="/board/create" method="POST">
        <div class="createForm">
            <label >제목</label>
            <input type="text" name="b_title" class="createForm" placeholder = "게시판 제목">
        </div>
        <div class="createForm">
            <label >내용</label>
            <textarea rows="4" cols="15" name="b_detail" class="createForm" placeholder = "게시판 내용"></textarea>
        </div>
        <div class="createForm">
            <label >작성자</label>
            <input type="text" name="b_writer" class="createForm" placeholder = "작성자">
        </div>
        
        <div class="Formfooter">
                <button type="submit" class="btn_button">작성하기</button>
        </div>            
        
    </form>
 
    
</body>
</html>
 
cs

(create.jsp)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Succes</title>
</head>
<body>
 
<p>회원가입이 ${result }하셨습니다.</p>
 
</body>
</html>
cs

(succes.jsp)


Tip)

 <form action="/board/create" method="POST"> 여기서

action을 생략하고 
<form method="POST">만 입력하셔도 정상적으로 실행이 됩니다.

action 이라는 속성을 입력을 안하시면 현재경로로 인식을 하게됩니다.

(한 마디로 작성하기버튼을 누르면 현재경로의 POST방식으로 요청하는 것이죠.)





(추후 CRUD기능을 완성하고 나서

CSS와 Jquery /Ajax를 응용하여 화면을 꾸미도록 하겠습니다.)





생성 후 servlet-context.xml에 다음과같이 입력해주세요

    <context:component-scan base-package="org.hello.dao"></context:component-scan>
    <context:component-scan base-package="org.hello.service"></context:component-scan>
    <context:component-scan base-package="org.hello.controller" />
    <context:component-scan base-package="org.hello.domain" />








한번 잘되나 실행해보겠습니다.

(프로젝트를 Run As를 시켜서 확인해보세요.)


인터넷 창을 켜서 http://localhost:8081/board/create 입력하고

다음과 같이 입력해봅시다.



-작성하기누르면






-성공적으로 보내졌습니다.

(BoardController에서 Model클래스 사용해서

model.addAttribute("result""성공");을 입력했기 때문에

"성공"하셨습니다.가 화면에 출력되는 것 입니다.

(실제로 실행시켜보니 Model이 어떤 역할을 하는지 이해가 되셨을 겁니다.)


실제 DB에 데이터가 Insert가 되었는지 워크벤치에서 확인해보세요.





성공적으로 데이터가 넣어졌습니다.

(CRUD중에 C를 한것입니다.)


이렇게 데이터가 입력이되고 페이지를 새로고침(F5)를 하게 된다면

계속해서 똑같은 데이터가 DB에 저장이됩니다.(즉 도배가 가능합니다.)

이러한 도배를 방지하기 위해서 게시판을 등록 후 리다이렉트를 이용하여

목록을 조회하는 페이지로 이동하게 만듭니다.


BoardController의 /create(POST방식)을 다음과 같이 수정합니다.



1
2
3
4
5
6
7
8
9
10
11
    @RequestMapping(value = "/create",method=RequestMethod.POST )
    public String createPOST(BoardVO board, RedirectAttributes rttr) throws Exception{
        System.out.println("/board/create POST방식 입니다.");
        System.out.println(board.toString());
        
        service.create(board);
        
        //return "/board/succes";
        rttr.addFlashAttribute("msg""성공");
        return "redirect:/board/listAll";
    }
cs


return "/board/succes" 대신 return "redirect:/board/listAll"; 입력합니다.

Model 대신 RedirectAttributes를 사용합니다.


Model을 사용하게되면 리다이렉트를해도 URL에

result=성공이 계속해서 남아 있습니다.


RedirectAttributes는 리다이렉트 시점에 한 번만 사용되는 데이터를

만들 수 있습니다.(addFlashAttribute())


 rttr.addFlashAttribute("msg""success");를 입력하게 되면

한 번만 사용되는 데이터 + URL 상에는 보이지 않는 숨겨진 데이터의 형태로 전달

되기때문에 URL상에서는 확인이 불가능합니다.




그리고 다음과 같은 내용을 추가해주세요.


1
2
3
4
5
6
7
8
9
    @RequestMapping(value = "/listAll", method=RequestMethod.GET)
    public void listAll(Model model) throws Exception{
        
        System.out.println("전체목록 페이지");
        
        model.addAttribute("boardList", service.listAll());
        
    }
    
cs

(BoardController.java)



board폴더안에 listAll.jsp를 생성하고 다음과 같이 입력하니다.






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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page session="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    var result ='${msg}';
    
    if(result == '성공'){
        alert(result+'입니다.');
    }else{
        alert(result+'게시판등록 실패입니다.');
    }
    
</script>
 
 
</head>
<body>
 
    <table class="table table-board" border="1px" width="80%" align="center">
        <tr>
            <th style="width:10%" >글 번호</th>
            <th style="width:30%">제목</th>
            <th style="width:20%">작성자</th>
            <th style="width:20%">날짜</th>
            <th style="width:20%">조회수</th>
        </tr>
 
 
    <c:forEach items="${boardList }" var="boardVO">
        <tr>
            <td>${boardVO.b_no }</td>
            <td><a href="/board/detail?b_no=${boardVO.b_no}">${boardVO.b_title }</a></td>
            <td>${boardVO.b_writer }</td>
            <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm" value="${boardVO.b_date }" /> </td>
            <td><span> ${boardVO.b_count }</span> </td>
        </tr>
    </c:forEach>
    </table>
</body>
</html>
cs

(listAll.jsp)


그리고 다시한번



입력후 작성하기를 누르면



성공입니다와 함께



RedirectAttributes를 썼기 때문에URL에 msg="성공" 이라는 문구가

없는 것을 확인 할 수가있었습니다.






다음은 글의 상세내용을 볼 수 있도록 작업을 해보겠습니다.

상세내용을 보기위해서는 입력한 글 들의 고유한 번호를 가지고 찾아야

정확하게 해당글의 상세내용을 찾을 수 있기 때문에

DB 테이블 생성시 PK로 값을 둔 b_no값을가지고 상세내용을 찾도록 하겠습니다.



listAll.jsp의 입력한 부분중에

<td><a href="/board/detail?b_no=${boardVO.b_no}">${boardVO.b_title }</a></td> 라고 입력을 했기때문에

제목의 링크들은 각각 b_no값을 가지고 GET방식으로 요청을 하게됩니다.

ex)  <a href="/board/detail?b_no=40">게시판 테스트3</a>




BoardController에 다음과 같은 내용을 추가합니다.


1
2
3
4
5
6
7
8
    @RequestMapping(value ="/detall", method = RequestMethod.GET)
    public void detail(@RequestParam("b_no"int b_no, Model model ) throws Exception{
        
        System.out.println("글 번호"+b_no+"번의 상세내용 페이지");
        
        model.addAttribute(service.read(b_no));
        
    }
cs

(BoardController.java)



@RequestParam("b_no"int b_no

@RequestParam이라는 것은 파라미터를 받기위한 용도입니다.


@RequestParam("b_no"int b_no 라고 입력하고

/board/detail?b_no=40라고 요청을 받았다면

b_no의 값을 int형 b_no에 담아줘~ 라는 뜻 입니다.

즉, b_no = 40 이 된 것입니다.(정수 형)


Servlet에서의 HttpServletRequest에서의

request.getParameter("b_no")와 같은 동작을 한다고 생각하시면 되겠습니다.

(다만 HttpServletRequest와 다른점은 문자열/날짜/숫자 등 형변환이 가능합니다.)


model.addAttribute(service.read(b_no));


예전에도 말씀드렸다시피

model.addAttribute("ket값", "value값")대신

위와 값이 model.addAttribute("value값")만 적었다면

잘못된 것이 아니라


해당 코드를 보면 BoardVO클래스 객체인 것을 알 수 있습니다.

BoardVO가 소문자로 바뀐 것이 key값이라고 이해하시면됩니다.




(boardMapper.xml을 보시면


이렇게 되어있습니다.

즉, resultType이 BoardVO클래스이기 때문에 key값이 boardVO가 되는것입니다.)

중요한건 model.addtribute에서 key값(이름)을 넣지 않는다면 자동으로

클래스의 이름을 소문자로 시작해서 사용한다는 것입니다.)

















댓글