본문 바로가기
Web & Mobile/JSP

Lecture 55 - JSP(13) annotation, filter, 한글 encoding, decoding, 로그인 검사 필터, ServletContextListener, MVC 패턴

by Bennyziio 2019. 6. 3.
반응형

서블릿 사용시 web.xml을 사용하는데 여기에 다 써놓는게 힘들어서 나온게 annotation이다.

web.xml generate 체크 안하고 생성

@WebServlet({"/servlet01"})
public class ServletEx01 extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doProcess() 호출");
	}
}

@WebServlet({"/servlet01"}) 서블릿 어노테이션

ServletEx04.servlet.ServletEx

package servlet;

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;

@WebServlet({"/servlet01"})
public class ServletEx01 extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doProcess() 호출");
	}
}

web.xml에서 수정사항이 생기면 톰캣을 껏다 켜야 했는데 어노테이션은 그러지 않아도 자동 실행이 가능하다.

ServletEx04.servlet.ServletEx - 어노테이션에 servlet02 추가

package servlet;

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;

@WebServlet({"/servlet01", "/servlet02"})
public class ServletEx01 extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doProcess() 호출");
	}
}

ServletEx04.servlet.ServletEx - 어노테이션에 옵션 정규문장

package servlet;

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;

@WebServlet(urlPatterns = {"/servlet01", "/servlet02"})
public class ServletEx01 extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doProcess(req, resp);
	}
	
	protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doProcess() 호출");
	}
}

ServletEx04.servlet.ServletEx02 - Servlet으로 만들기

package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ServletEx02
 */
@WebServlet(
		urlPatterns = { 
				"/ServletEx03", 
				"/ServletEx04"
		}, 
		initParams = { 
				@WebInitParam(name = "user", value = "tester")
		})
public class ServletEx02 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ServletEx02() {
        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
		doProcess(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("doProcess 호출");
	}
}

필터
: HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 클래스이다. 필터는 객체의 형태로 존재하며 클라이언트에게서 오는 요청(request)과 최종 자원(JSP, 서블릿, 기타 자원) 사이에 위치하여 클라이언트의 요청 정보를 알맞게 변경할 수 있다. 또한 필터는 최종 자원과 클라이언트로 가는 응답(response) 사이에 위치하여 최종 자원의 요청 결과를 알맞게 변경할 수 도 있다.

위 그림을 보면 필터는 클라이언트와 자원 사이에 위치하고 있다. 실제 자원이 받는 요청 정보는 필터가 변경한 요청 정보가 되며, 또한 클라이언트가 보는 응답 정보는 필터가 변경한 응답 정보가 된다. 클라이언트와 자원 사이에 한 개의 필터만 존재할 수 있는 것은 아니며, 여러 개의 필터가 모여 하나의 필터 체인(chain)을 형성하게 된다.

위 그림과 같이 여러 개의 필터가 모여서 하나의 체인을 형성할 때 첫 번째 필터가 변경하는 요청 정보는 클라이언트의 요청 정보가 되지만, 체인의 두 번째 필터가 변경하는 요청 정보는 첫 번째 필터를 통해서 변경된 요청 정보가 된다. 즉, 요청 정보는 변경에 변경을 거듭하게 되는 것이다. 응답 정보의 경우도 요청 정보와 비슷한 과정을 거친다. 차이점이 있다면 필터의 적용 순서가 요청 때와는 반대라는 것이다.

필터는 정보를 변경할 뿐만 아니라 흐름도 변경할 수 있다. 즉, 필터는 클라이언트의 요청을 필터 체인의 다음 단계(결과적으로는 클라이언트가 요청한 자원)에 보내는 것이 아니라 다른 자원의 결과를 클라이언트에 전송할 수 있다. 필터의 이러한 기능은 사용자 인증이나 권한 검사와 같은 기능을 구현할 때 용이하게 사용할 수 있다.

필터의 구현

Filter 인터페이스

여기서 가장 중요한 것은 doFilter() 메서드이다 서블릿 컨테이너는 사용자가 특정한 자원을 요청했을 때 그 자원사이에 존재하는 경우 필터 객체의 doFilter() 메서드를 호출한다. 바로 이 시점부터 필터를 적용하기 시작한다. 

//2. 체인의 다음 필터 처리 
chain.doFilter(request, response);

FIlterEx01.filter.FilterEx01 - 필터의 구현
web.xml 포함해서 생성한다!!

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx01 implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("첫번째 destroy() 호출");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("첫번째 전처리");
		chain.doFilter(request, response);
		System.out.println("첫번재 후처리");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("첫번째 init() 호출");
	}

}

FilterEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>FilterEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
</web-app>

FilterEx01.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
Hello JSP
<%
	System.out.println("Hello JSP");
%>
</body>

</html>

FilterEx01.filter.FilterEx02

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx02 implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("두번째 destroy() 호출");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("두번째 전처리");
		chain.doFilter(request, response);
		System.out.println("두번째 후처리");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("두번째 init() 호출");
	}

}

FilterEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>FilterEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
  
  <filter>
  	<filter-name>filter02</filter-name>
  	<filter-class>filter.FilterEx02</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter02</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
</web-app>

톰캣을 재 실행 하면

FilterEx01.web - 두번째를 첫번째 위로 옮기면

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>FilterEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter02</filter-name>
  	<filter-class>filter.FilterEx02</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter02</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
  
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
</web-app>

위와 같이 console창에 두번째 전처리 -> 첫번째 전처리 순으로 처리되어 나간다

필터의 응용
: 필터를 사용하는 방법에는 제한이 없으며, 필터의 특징을 잘 활용하느냐에 따라서 필터의 응용 범위가 달라질 수 있다. 보통 다음과 같은 기능에 필터를 적용한다.
· 사용자 인증
· 캐싱 필터
· 자원 접근에 대한 로깅
· 응답 데이터 변환(HTML 변환, 응답 헤더 변환, 데이터 암호화 등)
· 공통 기능 실행

EncodingEx01 다이나믹 웹 프로젝트 생성 web.xml 포함

EncodingEx01.form

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- form.jsp -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
<form action="./form_ok.jsp" method="post">
이름 <input type="text" name="name" />
<input type="submit" value="전송" />
</form>
</body>

</html>

EncodingEx01.form_ok

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- form_ok.jsp -->
<%
	String name = request.getParameter("name");

	out.println("이름 : " + name);
%>

한글이 깨져 나오므로 request.setCharacterEncoding("utf-8");을 추가해 준다

EncodingEx01.form_ok

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- form_ok.jsp -->
<%
	request.setCharacterEncoding("utf-8");
	
	String name = request.getParameter("name");

	out.println("이름 : " + name);
%>

이걸 매번 해줄려면 귀찮기 때문에 필터 처리 해준다

EncodingEx01.filter.FilterEx01

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx01 implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		arg0.setCharacterEncoding("utf-8");
		
		arg2.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

}

EncodingEx01.form_ok

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- form_ok.jsp -->
<%
	//request.setCharacterEncoding("utf-8");
	
	String name = request.getParameter("name");

	out.println("이름 : " + name);
%>

EncodingEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>EncodingEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
</web-app>

FilterEx01에 작성한 

@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		arg0.setCharacterEncoding("utf-8");
		
		arg2.doFilter(arg0, arg1);
	}

에서 arg0.setCharacterEncoding("utf-8");가 request 부분인데 이것에 의해서 인코딩이 되어 한글이 정상출력된다.

EncodingEx01.filter.FilterEx02

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx02 implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub	
		arg2.doFilter(arg0, arg1);
		
		RequestDispatcher dispatcher
			= arg0.getRequestDispatcher("error");
		dispatcher.forward(arg0, arg1); 	// 받은 내용을 다른 내용으로 바꿀때 forward 사용
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

}

EncodingEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>EncodingEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
  
  <filter>
  	<filter-name>filter02</filter-name>
  	<filter-class>filter.FilterEx02</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter02</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
</web-app>

EncodingEx01.error

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
여기는 error.jsp
</body>

</html>

EncodingEx01.filter.FilterEx02

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx02 implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		String name = arg0.getParameter("name");
		
		if(name != null && !name.equals("")) {
			arg2.doFilter(arg0, arg1);
		} else {
			RequestDispatcher dispatcher
			= arg0.getRequestDispatcher("error.jsp");
			dispatcher.forward(arg0, arg1); 	// 받은 내용을 다른 내용으로 바꿀때 forward 사용
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

}

EncodingEx01.error

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
여기는 error.jsp
</body>

</html>

EncodingEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>EncodingEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
  
  <filter>
  	<filter-name>filter02</filter-name>
  	<filter-class>filter.FilterEx02</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter02</filter-name>
  	<url-pattern>/form_ok.jsp</url-pattern>
  </filter-mapping>
</web-app>

DecodingEx01.filter.FilterEx01

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx01 implements Filter {
	private String id;
	private String password;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		request.setAttribute("sid", id);
		request.setAttribute("spassword", password);
		
		chain.doFilter(request, response);
		
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		id = filterConfig.getInitParameter("id");
		password = filterConfig.getInitParameter("password");
	}

}

DecodingEx01.web - web에서 scott과 tiger의 초기값을 주었다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>DecodingEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  	<init-param>
  		<param-name>id</param-name>
  		<param-value>scott</param-value>
  	</init-param>
  	<init-param>
  		<param-name>password</param-name>
  		<param-value>tiger</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
</web-app>

DecodingEx01.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	String id = (String)request.getAttribute("sid");
	String password = (String)request.getAttribute("spassword");
	
	out.println("아이디 : " + id + "<br />");
	out.println("패스워드 : " + password + "<br />");
%>

DecodingEx01.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	String id = (String)request.getAttribute("sid");
	String password = (String)request.getAttribute("spassword");
	
	out.println("아이디 : " + id + "<br />");
	out.println("패스워드 : " + password + "<br />");
	
	request.setAttribute("sid", "바꾼 " + id);
	request.setAttribute("spassword", "바꾼 " + password);
%>

DecodingEx01.filter.FilterEx01

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx01 implements Filter {
	private String id;
	private String password;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		request.setAttribute("sid", id);
		request.setAttribute("spassword", password);
		
		chain.doFilter(request, response);
		
		System.out.println(request.getAttribute("sid"));
		System.out.println(request.getAttribute("spassword"));
		
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		id = filterConfig.getInitParameter("id");
		password = filterConfig.getInitParameter("password");
	}

}

로그인 검사 필터
: 회원제로 운용되는 사이트에 유료화 추세에 맞춰 사용자 인증을 거친 후 컨텐츠를 구매하도록 유도하는 사이트에 사용자 인증은 웹 사이트의 필수 기능이므로 각각의 JSP/서블릿 등의 코드에 사용자가 로그인했는지 여부를 판단하기 위한 코드를 구현할 수 있다. 하지만,  JSP/서블릿마다 사용자 인증 코드를 넣으면, 회원 인증 정책이 변경될 때마다 관련된 모든 코드를 변경해야 한다는 문제가 발생한다.

이런 문제는 인증 여부를 검사하는 필터를 사용해서 깔끔하게 해결할 수 있다. 즉, 필터에서 로그인했는지 여부를 판단하고, 로그인하지 않았다면 로그인 폼을 보여주는 페이지로 흐름을 이동시킬 수 있는 것이다.

FilterEx01.filter.LoginCheckFilter

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.catalina.servlet4preview.http.HttpServletRequest;

public class LoginCheckFilter implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpSession session = httpRequest.getSession(false);
		
		boolean login = false;
		if(session != null) {
			if(session.getAttribute("MEMBER") != null) {
				login = true;
			}
		}
		if(login) {
			chain.doFilter(request, response);
		} else {
			RequestDispatcher dispatcher = request.getRequestDispatcher("/loginForm.jsp");
			dispatcher.forward(request, response);
		}
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}

}

FilterEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>FilterEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>filter02</filter-name>
  	<filter-class>filter.FilterEx02</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter02</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
  
  <filter>
  	<filter-name>filter01</filter-name>
  	<filter-class>filter.FilterEx01</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filter01</filter-name>
  	<url-pattern>*.jsp</url-pattern>	<!-- *.jsp란 요청 들어오면 실행해라 -->
  </filter-mapping>
  
  <filter>
  	<filter-name>LoginCheck</filter-name>
  	<filter-class>filter.LoginCheckFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>LoginCheck</filter-name>
  	<url-pattern>/board/*</url-pattern>
  </filter-mapping>
</web-app>

FilterEx01.webcontent.LoginForm

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>로그인</title>
</head>

<body>
<form action="<%=request.getContextPath() %>/login.jsp">
아이디<input type="text" name="memberId">
암호<input type="password" name="password">
<input type="submit" value="로그인">
</form>
</body>

</html>

FilterEx01.webcontent.login

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String memberId = request.getParameter("memberId");
	session.setAttribute("MEMBER", memberId);
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>로그인</title>
</head>

<body>
로그인 처리
</body>

</html>

webfilter를 이용해서 web.xml에 필터를 추가안해주고도  filter 기능 사용하기 - 어노테이션 기법
FilterEx02.fitler.FilterEx01

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter("*.jsp")
public class FilterEx01 implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		
		System.out.println("전처리");
		
		chain.doFilter(request, response);
		
		System.out.println("후처리");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

}

FilterEx02.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- test.jsp -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
Hello Filter
</body>

</html>

FilterEx02.filter.FilterEx02 - create filter를 이용해서 filter 생성

package filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/**
 * Servlet Filter implementation class FilterEx02
 */
@WebFilter("/test2.jsp")
public class FilterEx02 implements Filter {

    /**
     * Default constructor. 
     */
    public FilterEx02() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		System.out.println("전처리");
		
		chain.doFilter(request, response);
		
		System.out.println("후처리");
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

FilterEx02.test2

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- test.jsp -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
Hello test2
</body>

</html>

MemberEx01

MemberEx01.login.LoginCheckFilter

package login;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpSession;

import org.apache.catalina.servlet4preview.http.HttpServletRequest;

/**
 * Servlet Filter implementation class LoginCheckFilter
 */
@WebFilter("/member/*")
public class LoginCheckFilter implements Filter {

    /**
     * Default constructor. 
     */
    public LoginCheckFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpSession session = httpRequest.getSession(false);
		
		boolean login = false;
		if(session != null) {
			if(session.getAttribute("aId") != null && session.getAttribute("aGrade") != null) {
				login = true;
			}
		}
		
		if(login) {
			chain.doFilter(request, response);
		} else {
			RequestDispatcher dispatcher
				= request.getRequestDispatcher("/loginForm.jsp");
			dispatcher.forward(httpRequest, response);
		}
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

MemberEx01.member.loginSuccess

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- loginSucess.jsp -->
<%
	String aId = (String)session.getAttribute("aId");
	String aGrade = (String)session.getAttribute("aGrade");
	
	out.println("아이디 : " + aId + "<br />");
	out.println("등급 : " + aGrade + "<br />");
	
	out.println("<a href='./logOut.jsp'>로그아웃</a>");
%>

MemberEx01.member.logOut

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- logOut.jsp -->

<%
	session.invalidate();

	out.println("<script type='text/javascript'>");
	out.println("alert('로그아웃 되었습니다.');");
	out.println("location.href='../loginForm.jsp';");
	out.println("</script>");
%>

MemberEx01.loginForm

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- loginForm -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>

<form action="/MemberEx01/loginCheck.jsp" method="post">
아이디 <input type ="text" name="id" />
비밀번호 <input type="password" name="password" />
<input type="submit" value="로그인" />
</form>

</body>

</html>

MemberEx01.loginCheck

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- loginCheck.jsp -->
<%
	request.setCharacterEncoding("utf-8");

	String id = request.getParameter("id");
	String password = request.getParameter("password");
	
	String uId = "tester";
	String uPassword = "123456";
	
	int flag = 1;
	if(id.equals(uId) && password.equals(uPassword)) {
		flag = 0;
		
		session.setAttribute("aId", id);
		session.setAttribute("aGrade", "B");
	}
	
	out.println("<script type='text/javascript'>");
	if(flag == 0) {
		out.println("alert('로그인되었습니다.');");
		out.println("location.href='./member/loginSuccess.jsp';");
	} else {
		out.println("alert('로그인에 실패했습니다.');");
		out.println("history.back()");
	}
	out.println("</script>");
%>

위와 같이 memeber/loginSuccess.jsp로 경로를 지정해도 loginForm의 화면이 나온다. 이유는 필터가 중간에 경로를 읽다가 채갔기 때문이다.

위 그림과 같이 필터가 중간에 경로를 채갔어도 잘 진행된다.

ServletContextListener를 이용한 이벤트 처리
: 웹 컨테이너는 웹 어플리케이션(컨텍스트)이 시작되거나 종료되는 시점에 클래스의 메서드를 실행할 수 있는 기능을 제공하고 있다. 이 기능을 사용하면 웹 어플리케이션을 실행할 때 필요한 초기화 작업이나 웹 어플리케이션이 종료된 후 사용된 자원을 반환하는 등의 작업을 수행할 수 있다.

웹 어플리케이션이 시작되고 종료될 때 특정한 기능을 실행하는 법
1. javax.servlet.ServletContextListener 인터페이스를 구현한 클래스를 작성한다.
2. web.xml 파일에 1번에서 작성한 클래스를 등록한다.
javax.servlet.ServletcontextListener 인터페이스는 웹 어플리케이션이 시작되거나 종료될 때 호출할 메서드를 정의한 인터페이스로서, 다음과 같은 두 개의 메서드를 정의하고 있다.
· public void contextInitialized(ServletContextEvent sce)
  웹 어플리케이션을 초기화할 때 호출한다
· public void contextDestroyed(ServletcontextEvent sce)
  웹 어플리케이션을 종료할 때 호출한다.

ListenerEx01
web.xml을 만들어준다

package listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ListenerEx01 implements ServletContextListener {

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		System.out.println("contextDestroyed() 호출");

	}

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		System.out.println("contextInitialized() 호출");
	}
}

ListenerEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>ListenerEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <listener>
  	<listener-class>listener.ListenerEx01</listener-class>
  </listener>
</web-app>

ListenerEx01.WebContent.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
Hello Listener
</body>

</html>

ListenerEx01.listner.ListenerEx02

package listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class ListenerEx02 implements ServletContextAttributeListener {

	@Override
	public void attributeAdded(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("값 추가");
		System.out.println(arg0.getName() + " : " + arg0.getValue());
	}

	@Override
	public void attributeRemoved(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("값 제거");
	}

	@Override
	public void attributeReplaced(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("값 변경");
	}

}

ListenerEx01.web

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>ListenerEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>listener.ListenerEx01</listener-class>
  </listener>
  <listener>
    <listener-class>listener.ListenerEx02</listener-class>
  </listener>
</web-app>

ListenerEx01.WebContent.test

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	ServletContext context = getServletContext();

	context.setAttribute("name", "박문수");
	context.setAttribute("name", "홍길동");
	context.removeAttribute("name");
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
Hello Listener
</body>

</html>

ListenerEx01.listener.ListenerEx03 - Create Listener로 생성하는 방법

package listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class ListenerEx03
 *
 */
@WebListener
public class ListenerEx03 implements ServletContextListener {

    /**
     * Default constructor. 
     */
    public ListenerEx03() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }
	
}

MVC 패턴 구현
: 모델1은 빈즈를 이용했다면 MVC는 패턴으로 기존에 것을 바꾸겠다는 개념이다.
모델 2 구조 기반의 MVC 패턴 구현은 JSP 개발자라면 반드시 습득해야 할 기본 기법이다.

모델 2 구조와 MVC 패턴
: JSP 모델 웹 어플리케이션의 구조는 크게 모델 1 구조와 모델 2 구조로 나뉜다. JSP에서 모든 로직과 출력을 처리하느냐 아니면 JSP에서는 출력만 처리하느냐에 따라서 모델 1 구조와 모델 2 구조로 구분된다.

모델 1 구조
: 모델 1 구조는 JSP를 이용한 단순한 모델이다. 지금까지 예제로 작성한 JSP 페이지가 모델 1 구조를 사용하고 있다. 

모델 1 구조는 위 그림과 같이 웹 브라우저의 요청을 JSP가 직접 처리한다. 웹 브라우저의 요청을 받은 JSP는 자바빈이나 서비스 클래스를 사용해서 웹 브라우저가 요청한 작업을 처리하고 그 결과를 클라이언트에 출력한다.
JSP 페이지에서 웹 브라우저가 요청한 것들을 처리한다는 것은 JSP 페이지에 비지니스 로직을 처리하기 위한 코드와 웹 브라우저에 결과를 출력하는 코드가 섞인다는 것을 의미한다.

모델 2 구조
: 모델 2 구조는 모델 1 구조와 달리 웹 브라우저의 요청을 하나의 서블릿이 받는다. 서블릿은 웹 브라우저의 요청을 알맞게 처리한 후 그 결과를 보여줄 JSP 페이지로 포워딩한다. 포워딩을 통해 요청 흐름을 받은 JSP 페이지는 결과 화면을 클라이언트에 전송한다. 이 과정에서 서블릿이 로직을 처리한다.

모델 2 구조의 특징은 웹 브라우저의 모든 요청을 단일 진입점, 즉 하나의 서블릿에서 처리한다는 점이다. 하나의 서블릿이 웹 브라우저의 모든 요청을 받기 때문에, 서블릿은 웹 브라우저의 요청을 구분하는 방법이 필요하다. 서블릿은 웹 브라우저의 요청을 처리한 후 웹 브라우저에 보이게 될 응답화면을 생성할 JSP를 선택한다. 모델 2 구조의 이러한 특징 때문에, MVC(Model-View-Controller) 패턴을 이용해서 웹 어플리케이션을 구현할 때 모델 2 구조를 사용한다.

MVC 패턴
: MVC(Model-View-Controller)
· 모델 : 비즈니스 영역의 로직을 처리한다.
· 뷰 : 비즈니스 영역에 대한 프레젠테이션 뷰(즉, 사용자가 보게 될 결과 화면)를 담당한다.
· 컨트롤러 : 사용자의 입력 처리와 흐름 제어를 담당한다.

MVC 패턴과 모델2 구조의 매핑
· 컨트롤러 = 서블릿
· 모델 = 로직 처리 클래스, 자바빈
· 뷰 = JSP
· 사용자 = 웹 브라우저 내지 휴대폰과 같은 다양한 기기

MVC의 컨트롤러 : 서블릿
: 모델 2 구조에서 서블릿은 MVC 패턴의 컨트롤러 역할을 한다. 서블릿은 웹 브라우저의 요청과 웹 어플리케이션의 전체적인 흐름을 제어한다.

MVC의 뷰 : JSP
: 모델 2 구조에서 JSP는 뷰 역할을 담당한다. 비즈니스 로직과 관련된 코드가 없는 점을 제외하면 일반 JSP와 동일한 형태를 취한다. 뷰 역할을 하는 JSP는 웹 브라우저가 요청한 결과를 보여주는 프레젠테이션의 역할을 할 뿐만 아니라 웹 브라우저의 요청을 컨트롤러에 전달해주는 매체가 되기도 한다.

MVC의 모델
: 컨트롤러는 서블릿을 통해서 구현하고 뷰는 JSP를 통해서 구현하는데 모델은 명확하게 어떤 것을 통해서 구현한다는 규칙은 없다. 비즈니스 로직을 처리해주면 모델이 될 수 있다.

MVC 패턴
parameter(command)
        서블릿명?action=list
        서블릿명?action=write
url
        list.do
        write.do
-------------------------------------------------

controller?action=view1         -> view1.jsp
controller?action=view2         -> view2.jsp

view1.do                        -> view1.jsp
view2.do                        -> view2.jsp

ControllerEx01.servlet.ControllerEx01

package servlet;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.RequestDispatcher;
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 ControllerEx01
 */
@WebServlet("/Controller")
public class ControllerEx01 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ControllerEx01() {
        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
		doProcess(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		try {
			request.setCharacterEncoding("utf-8");
			
			String action = request.getParameter("action");
			String url = "";
			if(action == null || action.equals("") || action.equals("view1")) {
				url = "/view1.jsp";
			} else if(action.equals("view2")) {
				url = "/view2.jsp";
			} else {
				url = "/error.jsp";
			}
			
			RequestDispatcher dispatcher = request.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	

}

ControllerEx01.WebContent.view1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>

view1.jsp

</body>

</html>

ControllerEx01.WebContent.view2

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>

view2.jsp

</body>

</html>

ControllerEx01.model1.View1Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class View1Model implements Model{

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("View1Model 호출");
	}
	
}

ControllerEx01.model1.View2Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class View2Model implements Model {

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("View2Model 호출");
	}
	
}

ControllerEx01.model1.Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Model {
	public void execute(HttpServletRequest request, HttpServletResponse response);
}

ControllerEx01.servlet.ControllerEx01

package servlet;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model1.Model;
import model1.View1Model;
import model1.View2Model;

/**
 * Servlet implementation class ControllerEx01
 */
@WebServlet("/Controller")
public class ControllerEx01 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ControllerEx01() {
        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
		doProcess(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		try {
			request.setCharacterEncoding("utf-8");
			
			String action = request.getParameter("action");
			String url = "";
			
			Model model = null;
			if(action == null || action.equals("") || action.equals("view1")) {
				model = new View1Model();
				model.execute(request, response);
				url = "/view1.jsp";
			} else if(action.equals("view2")) {
				model = new View2Model();
				model.execute(request, response);
				url = "/view2.jsp";
			} else {
				url = "/error.jsp";
			}
			
			RequestDispatcher dispatcher = request.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

ControllerEx01.WebContent.form

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- form.jsp -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>
<form action="./Controller" method="post" >
<input type="hidden" name="action" value="view1" />
아이디 <input type="text" name="id" />
<input type="submit" value="전송" />
</form>
</body>

</html>

ControllerEx01.model1.View1Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class View1Model implements Model{

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("View1Model 호출");
		
		String id = request.getParameter("id");
		System.out.println("id : " + id);
	}
}

ControllerEx01.model1.View1Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class View1Model implements Model{

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("View1Model 호출");
		
		String id = request.getParameter("id");
		System.out.println("id : " + id);
		
		String sid = (String)request.getAttribute("sid");
		System.out.println("sid : " + sid);
	}	
}

ControllerEx01.model1.View1Model

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class View1Model implements Model{

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("View1Model 호출");
		
		String id = request.getParameter("id");
		System.out.println("id : " + id);
		
		String sid = (String)request.getAttribute("sid");
		System.out.println("sid : " + sid);
		
		request.setAttribute("rid", id);
	}	
}

ControllerEx01.WebContent.view1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>Insert title here</title>
</head>

<body>

view1.jsp<br />
rid : <%=(String)request.getAttribute("rid") %><br />
sid : <%=(String)request.getAttribute("sid") %><br />

</body>

</html>

 

반응형

댓글