Certification/Spring(2V0-72.22, SCP)

Spring MVC - View / JSP

엘호리스 2018. 8. 7. 21:16

Spring MVC 에서 View 는 사용자가 보게 될 화면 결과인 JSP이다.

JSP는 html로 변환되어 사용자에게 보여지는데 JSP 태그문법을 알아야 한다.


JSP 파일은 url을 통한 직접적인 접근을 하지 못하게 WEB-INF 폴더 아래에 위치하게 한다.

그리고 DispatcherServlet을 통해 HandlerMapping, HandlerAdapter를 통해 컨트롤러에 도달하고

@RequestMapping을 통해 ViewResolver를 통해 경로를 변환받아 요청에 대한 응답을 받는다.

여기서 중요한건 JSP 파일의 위치이다. 반드시 WEB-INF 하위에 위치해야 한다. 하위 디렉토리 생성해 구조화 하면 된다.


* WEB-INF 디렉토리는 외부에서 접근이 불가능하다.

ViewResolver 소스는 JSP 파일 경로를 변환해주는 역할을 한다.

1
2
3
4
5
<!-- 뷰 리졸버 : 뷰(jsp 페이지)의 접두어,접미어 설정 -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>
cs


JSP 파일들은 views 폴더 아래에 위치해 있다.


member_list.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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>회원목록</h2>
<input type="button" value="회원등록"
    onclick="location.href='${path}/member/write.do'">
<table border="1" width="700px">
    <tr>
        <th>아이디</th>
        <th>이름</th>
        <th>이메일</th>
        <th>가입일자</th>
    </tr>
    <c:forEach var="row" items="${list}"
    <tr>
        <td>${row.userid}</td>
        <td>
        <a href="${path}/member/view.do?userid=${row.userid}">${row.name}</a>
        </td>
        <td>${row.email}</td>
        <td><fmt:formatDate value="${row.join_date}" pattern="yyyy-MM-dd HH:mm:ss" /> </td>
    </tr>
    </c:forEach>    
</table>
</body>
</html>
cs

jsp파일에서 우린 의문이 생길 수 있다. 변수를 의미하는 ${path}와 ${list}는 어디서 오는것일까?

위 member_list.jsp 파일을 컨트롤 하는 컨트롤러를 한번 살펴보자.


Controller는 기본적으로 View 이름을 리턴한다. 동시에 Model을 이용해 데이터를 넘길 수도 있다.

MemberController.java("member/list.do" 매핑 되어있는 메서드를 살펴보자)

모델에 MemberDTO라는 객체 자료형으로 만들어진 list를 세팅하는 것을 볼 수 있다.

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.example.spring01.controller;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
import com.example.spring01.model.dto.MemberDTO;
import com.example.spring01.service.MemberService;
 
@Controller //스프링에서 관리하는 컨트롤러 빈으로 등록
public class MemberController {
    //MemberService 인스턴스를 주입시킴
    @Inject
    MemberService memberService;
    
    @RequestMapping("member/list.do"//url mapping
    public String memberList(Model model) {
        List<MemberDTO> list=memberService.memberList();
        model.addAttribute("list", list);
        //   WEB-INF/views/member/member_list.jsp로 포워딩
        return "member/member_list";
    }
    
    @RequestMapping("member/write.do"//url mapping
    public String write() {
        //  /WEB-INF/views/member/write.jsp로 포워딩
        return "member/write";
    }
    //@ModelAttribute : 폼에서 전달된 값을 저장하는 객체    
    @RequestMapping("member/insert.do")
    public String insert(@ModelAttribute MemberDTO dto) {
        //System.out.println(dto);        
        memberService.insertMember(dto);
        return "redirect:/member/list.do";
    }
    //@RequestParam  : request.getParameter("변수명") 대체    
    @RequestMapping("member/view.do")
    public String view(
            @RequestParam String userid, Model model) {
        //모델에 자료 저장
        model.addAttribute(
                "dto", memberService.viewMember(userid));
        // view.jsp로 포워딩
        return "member/view"
    }
    // java.util.Date    
    @RequestMapping("member/update.do")
    public String update(MemberDTO dto, Model model) {
        //비밀번호 체크
        boolean result=
memberService.checkPw(dto.getUserid(), dto.getPasswd());
        if(result) { //비밀번호가 맞으면
            //회원정보 수정
            memberService.updateMember(dto);
            //수정 후 목록으로 이동
            return "redirect:/member/list.do"//redirect
        }else { //비밀번호가 틀리면
            model.addAttribute("dto", dto);
            model.addAttribute("join_date"
, memberService.viewMember(dto.getUserid()).getJoin_date());
            model.addAttribute("message""비밀번호를 확인하세요.");
            return "member/view"//forward
        }
    }
    @RequestMapping("member/delete.do")
    public String delete(
            String userid, String passwd, Model model) {
        boolean result=memberService.checkPw(userid, passwd);
        if(result) { //비번이 맞으면 삭제 => 목록으로 이동
            memberService.deleteMember(userid);
            return "redirect:/member/list.do";
        }else { //비번이 틀리면 되돌아감
            model.addAttribute("message","비밀번호를 확인하세요.");
            model.addAttribute(
                    "dto", memberService.viewMember(userid));
            return "member/view";
        }
    }
}
cs


그러면 의문으로 남은 ${path}는 어디서 오는 것일까?


include되어 있는 header.jsp 파일을 들여다 보면 JSTL 태그라이브러리에서 지원하는 변수 지원 태그를 사용한게 보인다.

pageContext.request.contextPath가 길어서 path로 지정해놓은 것이다.

1
2
3
4
5
6
7
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="path" 
value="${pageContext.request.contextPath}" />
<script src="${path}/include/jquery-3.2.1.min.js"></script>
cs