본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 63일차 - HttpSession, @WebServlet, Filter

HttpSession


HttpSession 인터페이스는 둘 이상의 page request에서 사용자를 식별하거나, 웹 사이트를 방문하고 해당 사용자에 대한 정보를 저장하는 방법을 제공한다.
Servlet container는 HttpSession를 사용하여 HTTP client - HTTP server 간의 세션을 생성한다. 이 때, 세션은 한 명의 사용자에 해당한다. 서버는 Cookie, rewriting URL와 같은 방법으로 세션을 유지하면서 관리할 수 있다. 객체를 세션에 바인딩하여 사용자 정보를 유지할 수 있다.

1. getSession(), getSession(true)
HttpSession이 존재하면 현재 HttpSession을 반환하고 존재하지 않으면 새로 세션을 생성한다.

2. getSession(false)
HttpSession이 존재하면 현재 HttpSession을 반환하고 존재하지 않으면 새로 생성하지 않고 null을 반환한다.

 

 

HttpServlet

 

HttpServlet은 서블릿이 웹상에서 HTTP 프로토콜을 이용해 서비스를 처리하기 위해 반드시 상속받아야 하는 클래스이다.

즉, 모든 서블릿 클래스의 상위 클래스는 HttpServlet이어야 한다.

 

 

@WebServlet

 

서블릿 매핑하는 방법에는 web.xml에 직접 작성하거나, 어노테이션으로 하는 방법이 있다.

web.xml에서 매핑을 할 경우, 외부의 파일인 web.xml에서 설정해주어야 했기 때문에 모든 설정을 한눈에 볼수 있지만, 실제파일과 연관관계를 찾기 힘들다는 단점이 있다. 

어노테이션으로 작성하면 관련 있는 설정을 클래스에 바로 설정할 수 있는 장점이 있지만 설정이 각각 파일에 흩어져있다는 단점이 있다.(아이디 도구를 사용하면 쉽게 볼 수 있음)

 

어노테이션은 '주석'이다. 클래스 선언부 위에 어노테이션을 작성해서 매핑을 할 수 있다.

어노테이션안에 경로를 입력하면 클라이언트에서, 해당 경로를 입력할 때 알아서 톰캣서버가 찾아서 실행해주게 된다.
web.xml 파일과 중복된 값이 있으면 충돌이 일어나기 때문에 한 곳에서만 사용해야 된다.

@WebServlet("/index")
@WebServlet(name = "HomeController", urlPatterns = {"/home", "/", "/index"})

 

 

Filter


필터를 구현하기 위해 Servlet/Jsp에서는 javax.servlet.Filter라는 인터페이스를 제공하며 이 인터페이스를 구현하도록 되어 있다.

Filter 인터페이스의 메서드는 다음과 같이 구성되어있다.

package javax.servlet;
 
import java.io.IOException;
 
public interface Filter {
 
    public void init(FilterConfig filterConfig) throws ServletException;
    
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException; 
 
    public void destroy();
}

 

1. public void init(FilterConfig filterConfig)
웹컨테이너(톰캣)이 시작될 때 필터 객체를 생성하는데, 이때 객체가 생성되면서 최초에 한 번 호출되는 메서드다. FilterConfig 객체를 넘겨주기 때문에 이를 통해 여러가지 설정값을 넘겨받을 수 있고 필터에서 처리시 필요한 객체 등을 초기화(예를들어 JDBC 커넥션 등) 하는데 사용된다.

2. public void destroy()
필터 객체가 제거될 때 실행되는 메서드이다. 보통 초기화시 생성했던 자원들을 종료하는 기능에 사용된다.

 

3. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
필터의 핵심 메서드이다. doFilter()는 클라이언트의 요청이 있을때마다 매번 실행된다.

ServletRequest와 ServletResponse 객체를 넘겨주기 때문에 이를 가지고 요청과 응답을 조작할 수 있다.

그리고 FilterChain을 통해 조작 이후 요청을 원래 목적지인 서블릿으로 전달할 수 있다.

 

 

4. Filter 등록

 

(1) web.xml

<?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_4_0.xsd" version="4.0">
  <display-name>web05</display-name>
  <welcome-file-list>
    <welcome-file>/index</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>LoginFilter</filter-name>
  	<filter-class>web05.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>LoginFilter</filter-name>
  	<url-pattern>/guestbook/*</url-pattern>
  </filter-mapping>
</web-app>

 

(2) 어노테이션

package web05;

import java.io.IOException;

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

@WebFilter("/guestbook/*")
public class LoginFilter implements Filter {
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("필터를 통해 동일한 작업을 before 수행할 수 있습니다.");
		
		chain.doFilter(request, response);
		
		System.out.println("필터를 통해 동일한 작업을 after 수행할 수 있습니다.");
	}
}

 

 

Filter 연습

 

1. LoginFilter

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@WebFilter("/guestbook/*")
public class LoginFilter implements Filter {
	private boolean logincheck(HttpSession session) {
		if (session == null) {
			return false;
		}
		
		return session.getAttribute("login") != null;
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest req = ((HttpServletRequest) request); 
		HttpSession session = req.getSession(false);
		if (!logincheck(session)) {
			((HttpServletResponse) response).sendRedirect("../login.jsp");
			return;
		}
		chain.doFilter(request, response);
	}
}

 

2. EncodingFilter

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// /** -> 모든 하위경로
@WebFilter("/**")
public class EncodingFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest req =(HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		
		chain.doFilter(req, resp);
	}
}