본문 바로가기
JSP/정리

[jsp/개발방법론] FrontController 패턴

by 미네밍 2017. 1. 20.

<FrontController 패턴>


<url-pattern>


1. 디렉터리 패턴

서블릿 맵핑과 비슷한 형태.


http://localhost:8181/jsp_ex1_memberex/Hello


1
2
http://localhost:8181/jsp_ex1_memberex/Hello
http://localhost:8181/jsp_ex1_memberex/World
cs


/Hello , /World 와 같은 식으로 '디렉토리' 형식을 말한다.

각 디렉토리 맵핑명을 가지고 별개의 서블릿을 찾아간다. Hello 서블릿과 World 서블릿을 찾아간다.


2. 확장자 패턴


1
2
http://localhost:8181/jsp_ex1_memberex/hello.do
http://localhost:8181/jsp_ex1_memberex/world.do
cs


확장자 패턴이 같다면, 그 확장자의 서블릿을 찾아간다. *.do 서블릿을 찾아간다는 점이 디렉터리 패턴과는 다르다.

다음 설명에서 조금 더 자세히 알아볼 수 있다.


<FrontController 패턴>


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



다음과 같이, 여러개의 요청을 따로 따로 처리하는 서블릿을 만드는 것이 아닌, 모든 요청을 처리하는 서블릿 하나를 만드는 방법이다.


예를 들면, 회원 정보 입력, 수정, 삭제 등등 많은 요청들을 처리하는 Front Controller 를 만드는 것이 그 예이다. 앞서 말한 "확장자 패턴" 을 사용하여 구현할 수 있다.


test.jsp

1
2
3
<a href="insert.do">insert</a>
<a href="update.do">update</a>
<a href="delete.do">delete</a>
cs


다음과 같은 코드가 있다고 하자. insert, update, delete 작업 모두가 .do 확장자로 되어있는 파일로 가도록 설정되어 있다.


FrontController.java (서블릿)

1
@WebServlet("*.do")
cs


특정 Servlet에 이렇게 annotation 을 적어주면, 확장자가 do 인 파일에 하는 요청은 무조건 자기에게 오라는 신호이다.

따라서, test.jsp의 insert, update, delete 세개의 모든 요청은 FrontController.java 서블릿 페이지로 가게 된다.


1
2
3
4
5
6
7
String uri =  request.getRequestURI();
String conPath = request.getContextPath();
String command = uri.substring(conPath.length()); //uri 의 길이에서 conPath의 길이 만큼 잘라낸 
        
System.out.println("conPath :" + conPath);
System.out.println("uri :" + uri);
System.out.println("command :" + command);
cs


요청을 한번에 받았다면 다음은 이것이 insert 인지, update 인지, delete 인지를 구분해야 할 것이다.

어디에서 온 요청인지 알고자 할 때는 다음과 같은 코드로 알 수 있다.




결과는 위와 같다.


1
2
3
4
5
if(command.equals("/insert.do")){
    //....
}else{
    //....
}
cs


또한 위처럼 command 값은 요청마다 다를 것이므로 조건으로 구분해 각각의 요청마다 어떠한 처리를 해 줄 것인지 작성해도 된다.

하지만, 조건문 안에서 모든 처리내용을 작성해 준다면 내용들이 너무 길어지는 문제가 생길 수도 있다.


<Command 패턴>


클라이언트들로부터 받은 요청들을 서블릿이 직접 '처리' 하지 않고, 각각 해당되는 클래스가 처리하도록 하는 방법이다.

요청은 한 곳에 집중시키고, 그 요청에 따른 처리는 다시 분산시켜주는 방식이다.




보통은 interface 를 하나씩 선언해준다. 

Command 클래스를 만들고, DAO 로부터 객체를 가져오는 작업을 해당 클래스에 기재한다. 


예시로, MemberDAO 라는 DAO클래스의 membersAll() 이라는 함수가 '회원 정보를 DB로 부터 가져와 ArrayList<MemberDTO> 형태로 반환하는 역할'을 한다고 가정해보자.

Service 라는 인터페이스 안에 ArrayList<MemberDTO> 를 반환형으로 가지는 execute 가 있다.


1
2
3
public interface Service {
    public ArrayList<MemberDTO> execute(HttpServletRequest request, HttpServletResponse response);
}
cs


다음 인터페이스는 다음과 같이 구현시켰다.


1
2
3
4
5
6
7
8
9
10
public class MembersAllService implements Service {
 
    @Override
    public ArrayList<MemberDTO> execute(HttpServletRequest request, HttpServletResponse response) {
        // TODO Auto-generated method stub
        MemberDAO dao = MemberDAO.getInstance();
        return dao.membersAll();
    }
 
}
cs


이 클래스는 Service 인터페이스를 구현했으므로, execute 함수를 반드시 작성하여야 한다. execute 함수는 결국 DB에서 회원정보를 가져오는 역할을 할 수 있다.


FrontController.java ( 서블릿 )

1
2
3
4
5
6
7
8
9
10
11
12
if(command.equals("/select.do")){
            
            Service service = new MembersAllService();
            ArrayList<MemberDTO> dtos = service.execute(request, response);
            
            for(int i = 0 ; i < dtos.size; i++){
                System.out.println("id : " + dtos.get(i).getId());
                System.out.println("id : " + dtos.get(i).getName());
            }
}else{
            //....
}
cs


돌아와서, 위에서 언급했던 FrontController 서블릿의 command 조건문을 다시 고려해본다. 

이 execute 함수는 command 조건문 안에 활용되었고, 데이터베이스에서 직접 가져오는 작업을 일일히 안에 적어주지 않아도 효율적이게 데이터를 가져올 수 있다.




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

[jsp/spring] DI  (0) 2017.02.03
[jsp] Forwarding(포워딩)  (0) 2017.01.20
[jsp] JSTL  (0) 2017.01.20
[jsp] EL(Expression Language)  (0) 2017.01.19
[jsp] 파일 업로드  (0) 2017.01.18

댓글