상세 컨텐츠

본문 제목

FrontController 패턴, Command 패턴 예제

WebProgramming/JSP

by ChrisMare 2018. 10. 28. 17:14

본문

FrontController 패턴

클라이언트의 다양한 요청들을 한곳으로 집중시켜서 개발 및 유지보수에 효율성을 극대화 시키는 패턴이다.

이를통해 해당하는 각각의 다양한 요청들에 따라 요청에 맞는 서블릿을 향하게 했는데 한곳으로 서블릿을 모아서 관리하는 것을 말한다.


이러한 형태를 FrontController 패턴적용 후



간단히 말하면 *.do 로 오는 모든 요청을 한 서블릿으로 받고

요청 uri 와 contextPath를 구한 후 이것을 contextPath만큼 substring하여 파일이름만을 구한 후 

이것으로 관리하는 것이다. 밑의 예제로 살펴보자.


FrontController EX )


doRequest.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
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>FrontController Test</title>
</head>
<body>
 
    <h1>FrontController Do Servlet Mapping</h1>
    <hr>
    
    <h2>Select.do</h2>
    <a href="select.do">select</a>
    <hr>
    <h2>Insert.do</h2>
    <a href="http://localhost:8181/FrontControllerEX/insert.do">insert</a>
    <hr>
    <h2>Update.do</h2>
    <a href="http://localhost:8181<%= request.getContextPath() %>/update.do">update</a>
    <hr>
    <h2>Delete.do</h2>
    <a href="<%=request.getContextPath() %>/delete.do">delete</a>
 
</body>
</html>
cs


DoFrontController.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
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
package com.jsplec.ex;
 
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class DoFrontController
 */
/* 확장자 패턴을 이용하여 *.do로 오는 모든 요청을 한곳에서 다 관리한다. ==> FrontController 패턴*/
@WebServlet("*.do")
public class DoFrontController extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DoFrontController() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        actionDo(request,response);
    }
 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        actionDo(request, response);
    }
    
    private void actionDo(HttpServletRequest request, HttpServletResponse response) {
        // TODO Auto-generated method stub
        System.out.println("actionDo");
        
        // uri = contextPath + 요청한 파일 이름
        String uri = request.getRequestURI();
        System.out.println("uri : " + uri);
        
        String contextPath = request.getContextPath(); 
        System.out.println("contextPath : " + contextPath);
        
        // command = uri - contextPath 길이만큼 빼면 요청한 파일 이름만 남는다.
        String command = uri.substring(contextPath.length());
        System.out.println("command : " + command);
        
// command에 있는 파일이름 만으로 관리 가능해진다.
        if(command.equals("/select.do")) {
            System.out.println("--------");
            System.out.println("select");
            System.out.println("--------");
        }else if(command.equals("/insert.do")) {
            System.out.println("--------");
            System.out.println("insert");
            System.out.println("--------");
        }else if(command.equals("/update.do")) {
            System.out.println("--------");
            System.out.println("update");
            System.out.println("--------");
        }else if(command.equals("/delete.do")) {
            System.out.println("--------");
            System.out.println("delete");
            System.out.println("--------");
        }
    }
 
}
 

cs


하지만 이렇게 FrontController 에서 모든 요청에 대한 처리를 하면(if 구문안) 소스가 길어지고 관리하기 힘들어진다.

이에 대한 대처가 다시 다른 Servlet으로 보내서 분산해서 관리해준다.

이것이 Command 패턴이다.


확장자가 같은 요청을 한곳으로 모은 후 각 요청의 처리를 다른 servlet 클래스로 보내서 처리하게 하는 방식이며

이것을 한번 예제로 보자.


예제로 들어가기전에 DB에 이러한 값이 들어가야된다는 전제이다.



예제 )


memberListSelect.jsp )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>MemberList 조회하러 가기</h1>
<hr>
<a href="memberList.do">전체 회원 조회</a>
</body>
</html>
cs


DoFrontController.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
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
86
87
88
89
90
package com.jsplec.ex;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class DoFrontController
 */
/* 확장자 패턴을 이용하여 *.do로 오는 모든 요청을 한곳에서 다 관리한다. ==> FrontController 패턴*/
@WebServlet("*.do")
public class DoFrontController extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DoFrontController() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("doGet");
        actionDo(request,response);
    }
 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("doPost");
        actionDo(request, response);
    }
    
    private void actionDo(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // TODO Auto-generated method stub
        System.out.println("actionDo");
        
        // uri = contextPath + 요청한 파일 이름
        String uri = request.getRequestURI();
        System.out.println("uri : " + uri);
        
        String contextPath = request.getContextPath(); 
        System.out.println("contextPath : " + contextPath);
        
        // command = uri - contextPath 길이만큼 빼면 요청한 파일 이름만 남는다.
        String command = uri.substring(contextPath.length());
        System.out.println("command : " + command);
        
        if(command.equals("/memberList.do")) {
            // 파일 이름으로 관련된 Dao로 보낸다.
            response.setContentType("text/html; charset=EUC-KR");
            PrintWriter writer = response.getWriter();
            writer.println("<html><head></head><body>");
            
            Action actionInterface = new MemberListAction();
            ArrayList<MemberDTO> dtos = actionInterface.action(request, response);
            for(int i=0;i<dtos.size();i++) {
                MemberDTO dto = dtos.get(i);
                String id = dto.getId();
                String pw = dto.getPw();
                String name = dto.getName();
                String email = dto.getEmail();
                String address = dto.getAddress();
                
                writer.println("id : "+ id +"<br>");
                writer.println("pw : "+ pw +"<br>");
                writer.println("name : "+ name +"<br>");
                writer.println("email : "+ email +"<br>");
                writer.println("address : "+ address +"<br>");
                writer.println("<hr>");
            }
            writer.println("</body></html>");
        }
    }
 
}
 
cs


MemberDTO.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
51
package com.jsplec.ex;
 
import java.sql.Timestamp;
 
public class MemberDTO {
    private String id;
    private String pw;
    private String name;
    private String email;
    private String address;
    private Timestamp mdate;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPw() {
        return pw;
    }
    public void setPw(String pw) {
        this.pw = pw;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public Timestamp getMdate() {
        return mdate;
    }
    public void setMdate(Timestamp mdate) {
        this.mdate = mdate;
    }
    
}
 
cs


MemberDAO.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
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
86
87
88
89
90
91
92
package com.jsplec.ex;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import javax.xml.ws.Response;
 
public class MemberDAO {
    
    public static final int MEMBER_NONEXISTENT = 0;
    public static final int MEMBER_EXISTENT = 1;
    public static final int MEMBER_JOIN_FAIL = 0;
    public static final int MEMBER_JOIN_SUCCESS = 1;
    public static final int MEMBER_LOGIN_PW_NO_GOOD = 0;
    public static final int MEMBER_LOGIN_SUCCESS = 1;
    public static final int MEMBER_IS_NOT = -1;
    
    private static MemberDAO instance = new MemberDAO();
    
    private MemberDAO() {} // 이를 통해 생성자를 접근 할 수 없다. 하지만 밑의  static 메소드를 통해 구현
                           // 싱글톤 패턴을 사용하여 객체 하나만을 만들어서 모든곳에서 다같이 사용할 있게 한다.
    
    public static MemberDAO getInstance() {
        return instance;
    }
    
    private Connection getConnection() {
        
        // server.xml에 Container추가해서 드라이버 로드 사전설정
        
        
        Context context = null;
        DataSource dataSource = null;
        Connection connection = null;
        try {
            context = new InitialContext();
            dataSource = (DataSource)context.lookup("java:comp/env/jdbc/Oracle11g");
            connection = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return connection;
    }
 
    public ArrayList<MemberDTO> getMemberList() {
        // TODO Auto-generated method stub
        ArrayList<MemberDTO> dtoList = new ArrayList<MemberDTO>();
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String query = "select * from member";
        
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(query);
            rs = pstmt.executeQuery();
            while(rs.next()) {
                MemberDTO dto = new MemberDTO();
                dto.setId(rs.getString("id"));
                dto.setPw(rs.getString("pw"));
                dto.setName(rs.getString("name"));
                dto.setEmail(rs.getString("email"));
                dto.setAddress(rs.getString("address"));
                dto.setMdate(rs.getTimestamp("mdate"));
                dtoList.add(dto);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            try {
                if(rs != null) rs.close();
                if(pstmt != null) pstmt.close();
                if(conn != null) conn.close();
            } catch (Exception e2) {
                // TODO: handle exception
                e2.printStackTrace();
            }
        }
        
        
        return dtoList;
    }
}
 
cs


Action.java ) -> interface

1
2
3
4
5
6
7
8
9
10
11
12
package com.jsplec.ex;
 
import java.util.ArrayList;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public interface Action {
    public ArrayList<MemberDTO> action(HttpServletRequest request, HttpServletResponse response);
 
}
 
cs


결과 )

이처럼 FrontController 패턴과 Command 패턴은 MVC라는 패턴 디자인에 많이 사용하게 되는 패턴들이다.

감사합니다.

'WebProgramming > JSP' 카테고리의 다른 글

MVC 패턴(Model1, Model2)  (5) 2018.10.29
Forwarding(포워딩)  (0) 2018.10.28
url-pattern (디렉토리 패턴, 확장자 패턴)  (0) 2018.10.26
JSTL 개요 및 설치, Core 사용법  (0) 2018.10.26
EL(Expression Language) 예제  (0) 2018.10.25

관련글 더보기

댓글 영역