IT한 것/java

서블릿 필터 개발시 주의할 점.

lovian 2008. 9. 15. 22:37
서블릿 필터 개발시 주의할 점

요놈의 필터를 개발할때에 반 필수적으로 ServletRequest, ServletResponse 인터페이스를 구현하거나 상속 받는다.

가장만만한 것이 랩핑을 이용하는 것이다.

뭐 자세한 방법이야 다들 알아서 잘들 할테지만,
최근 사정상 gzip 필터를 이용할 일이 있었는데, 문제 되는 것들이 많이 보였다.

요약하자면,
ServletResponse는 문자열 용으로 쓸 PrintWriter, 바이너리 용으로 쓸 ServletOutputStream 두가지를 사용하는데,
문제있는 gzip filter 들은 요, ServletOutputStream 만을 고려하여 만들어져 있었다.

물론 filter를 적용한 Web Application Server에 따라서 다를 수 있겠지만,
본인이 사용하던 Tomcat 4.1 버젼은 jsp 를 파싱할 때에는 PrintWriter로 html 를 파싱할때에는 ServletOutputStream으로 작동하는 것을 확인하였다.

그리고 PrintWriter -> OutputStream -> GZIPOutputStream -> ServletOutputStream 과 같은 형태로 데이터 변환이 되기 때문에,
GZIPOutputStream에 대해서만 flush, close를 하게 되면,
PrintWriter의 버퍼에 남아있던 데이터는 처리되지 않은 상태가 된다.
그런고로 올바른 결과가 안나온다.

그것만 문제인 줄 알았는데, PrintWriter를 auto flush모드로 생성하는 filter도 있었지만, 올바른 결과가 나오지를 않았다.
알고보니 PrintWriter가 flush를 해도 GZIPOutputStream의 finish, close를 호출하지 않는 이상은 압축 버퍼를 자동 반환하지 않는다 (뭔가 압축 알고리즘의 특성상인듯?)

하여튼
결론은
PrintWriter부터 ServletOutputStream까지 연계된 스트림들의 올바른 flush, close를 해야 무리없이 잘 작동하는 필터를 개발 할 수 있었다.

※그래도 close를 해야하는지 말아야하는지 혼란스럽다 ㅠㅠ