JAVA Servlet Filter

떡ol·2022년 8월 24일
0

필터(Filter)는 J2EE 표준 스펙 기능으로 디스패처 서블릿(Dispatcher Servlet)에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능을 제공한다. 즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되므로 디스패처 서블릿으로 가기 전에 요청을 처리하는 것이다.

WEB Context 구조유명한 그 그림

😊 이전 포스트에서 작업 (MultipartRequest) 하던 내용을 연장해서 연습해보도록 하겠다.

1. Filter 등록

WEB.xml context에 등록

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!--이부분 보면됨-->
	<filter>
		<filter-name>ParamFilter</filter-name>
		<filter-class>com.filter.ParamFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ParamFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
    <!--//이부분 보면됨-->

😊 뭐, 대충 설명 할 필요도 없겠지만 <filter> 부분에는 필터 이름과 해당 파일 클래스 위치를 작성하고, <filter-mapping>에서 적용할 필터의 이름과, url 범위를 지정하면 되겠다.(/* 이므로 하위 페이지 전부다.)
인코딩 필터는 UTF-8로 맞춰 작성한다. WEB컨테이너를 구동하면 꼭 들어가는 CharacterEncodingFilter 이므로 따로 설명은 안하고 추가 하겠다.

Java Bean으로 등록

@Configuration
public class WebConfig {
	// 예제입니다 본인의 filter에 맞게 수정하시면 됩니다. 
    @Bean
    public FilterRegistrationBean logFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new LogFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean logCheckFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new LoginCheckFilter());
        filterRegistrationBean.setOrder(2);
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

요렇게 등록하시면 됩니다. class 파일은 추후에 WebMvcConfigurer를 상속받아 interceptor, argumentResolver등 다양한 mvc 설정을 추가하는게 가능하다.

2. Filter를 상속받는 Class 파일을 만든다.

JAVA 파일

public class ParamFilter implements Filter{
	
	CommonsMultipartResolver multipartResolver = null; 
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		multipartResolver = new CommonsMultipartResolver();
	}
    
    @Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("paramFilter 시작");
		ParamMap paramMap = new ParamMap();
		setParameter(request, paramMap);
		request.setAttribute("FileMap",paramMap);
		
		chain.doFilter(request, response);
	}

	public ParamMap setParameter(ServletRequest request, ParamMap paramMap) {
		
		try {
			request.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		MultipartHttpServletRequest multipartRequest = null;
		if (multipartResolver.isMultipart((HttpServletRequest) request)) {
			multipartRequest = multipartResolver.resolveMultipart((HttpServletRequest) request);
			Iterator<String> i = multipartRequest.getFileNames();
			while(i.hasNext()) {
				String key = i.next();
				MultipartFile value = multipartRequest.getFile(key);
				System.out.println("11"+key+value.getOriginalFilename());
				paramMap.put(key,value);
			}
		}else {
			Enumeration <String> e = request.getParameterNames();
			while(e.hasMoreElements()) {
				String key = e.nextElement();
				String value = request.getParameter(key);
				System.out.println("22"+key+value);
				paramMap.put(key,value);
			}
		}
			
			
		return paramMap;

	}

}

JSP 파일

<form method="post" action="/fileUpload" enctype="multipart/form-data">
	<input type="file" name="myfile">
    <button type="submit">제출하기</button>

✔ JSP 파일을 만들고, @Controller에 @RequestMapping을 추가하는것을 잊지 말자, 그 소스까지는 안 올리겠다.

😊 JAVA파일을 세부적으로 설명하자면,Filter가 상속하는 자원 즉, Override 되는 매서드는 세가지가 있는데,

init(FilterConfig filterConfig)
destroy()
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

이렇게 구성되어있다.

  • init : 필터를 웹 컨테이너 내에 생성한 후 초기화할때 호출된다. 초기값을 셋팅하면 된다.
  • destroy : 필터가 웹 컨테이너에서 삭제될 때 호출된다.
  • doFilter : 이 메서드를 통해서 요청(Request)와 응답(Response)쌍이 체인을 통과할 때마다 컨테이너에서 호출된다. 체인을 따라서 계속 다음에 존재하는 필터로 이동하게 된다.

😊 여기서 중요한건 doFilter쪽이다. 요청이나 응답값을 받아 전처리 해주면 된다. 처리 후에는 FilterChain에 doFilter 매서드를 통해 다음 Filter 혹은 컨테이너로 진입을 진행 시키면 된다.

chain.doFilter(request, response); //작성을 잊지말자.

3. 기능설명

setParameter 부분은 이전 포스트에서 다뤘던 부분이다.
multipartResolver 통해서 요청된 File type의 데이터인지 확인(isMultipart)하고
multipartRequest 형변환하여 키 값과 파일 스트림 데이터를 Map에 저장하는 방법을 설명하고 있다.
Map에 담은 이 데이터를 Sevice단에서 OutputStream으로 불러와 read하여 사용하면된다.

ServletRequest ,ServletResponse를 알고있다면, 이해할 것이다.
더 자세한 설명은 제외하겠다.




참고자료들___
(참고) FilterChain 이란?

profile
하이

0개의 댓글