过滤器{
定义:Servlet的API中提供了一个Filter接口,当web开始时,某个类实现了该接口,那么该类就叫做过滤器。通过过滤器,开发人员可以在用户访问某个资源之前,对访问的请求和响应进行拦截。(当有多个过滤器,资源就会通过每一个过滤器)
步骤:
作用:1.实现filter接口
@Override public void init(FilterConfig filterConfig) throws ServletException { // 服务器启动时过滤器就被创建,执行该方法!只创建一次 // filterConfig对象可以获得web.xml文件配置的参数数据 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 作用是将拦截下来的请求.响应进行放行 chain.doFilter(request, response); } @Override public void destroy() { //web应用被移除,或者web服务器停止时,过滤器就会被销毁,同时执行该方法! }
2.在web.xml文件进行定义
<filter> <filter-name>filterDemo</filter-name> <filter-class>cn.review.servlet.FilterDemo</filter-class> <init-param><!--定义一些参数,可以在过滤器中获取该数据 --> <param-name></param-name> <param-value></param-value> </init-param> </filter> <filter-mapping> <filter-name>filterDemo</filter-name> <url-pattern>/*</url-pattern><!--定义拦截的路径--> <!--指定拦截器拦截哪种方式访问资源。request.forward.error.include --> <!-- 可以配置多个 --> <dispatcher>REQUEST</dispatcher> </filter-mapping>
1.通过检查用户的权限,来判断是否允许用户访问资源
2.通过拦截,解决浏览器和服务器之间的乱码
3.在过滤器放行之后,拿到response的内容,进行压缩处理等设置
}
实例{
解决全站的请求乱码问题
将数据进行压缩输出@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { // 为了调用子类方法 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 指定post提交编码 request.setCharacterEncoding("UTF-8"); // 指定响应输出的编码 //response的编码 response.setCharacterEncoding("UTF-8"); //通知浏览器打开方式 response.setHeader("content-type", "text/html;charset=utf-8"); // 放行 // 为了解决get提交的乱码问题,采用包装设计模式,进行操作 chain.doFilter(new MyRequest(request), response); } // 继承request的包装类 class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request= null; public MyRequest(HttpServletRequest request) { // 需要给包装类传递一个被包装的对象 super(request); this.request = request; } // 增强方法,解决get参数乱码 @Override public String getParameter(String name) { if(name==null || name.trim().equals("")){ return null; } String value = request.getParameter(name); if(value==null || value.trim().equals("")){ return null; } try { return new String(value.getBytes("iso8859-1"),request.getCharacterEncoding()); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } }
@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 为了获得response的数据,需要定义一个增强类, MyResponse myResponse = new MyResponse(response); chain.doFilter(request, myResponse); // 拿到缓冲流的数据 byte[] data = myResponse.getBos(); // 定义压缩类 ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(bos); // 把数据压缩写到了bos缓冲流 gzip.write(data); gzip.close(); byte[] gzipData = bos.toByteArray(); // 使用response对象将数据写出并告诉浏览器压缩格式 response.setHeader("content-encoding", "gzip"); response.setHeader("content-length", gzipData.length+""); response.getOutputStream().write(gzipData); } class MyResponse extends HttpServletResponseWrapper{ // 定义一个缓冲流,存储response的数据 ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 先需要获得被增强的对象,需要使用他的方法 HttpServletResponse response = null; public MyResponse(HttpServletResponse response) { super(response); this.response = response; } @Override public ServletOutputStream getOutputStream() throws IOException { // 当获得输出流的时候,传递一个自定义的流。以便将数据全部写入缓冲流 return new MyOutputStream(bos); } public byte[] getBos(){ return bos.toByteArray(); } } class MyOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bos; public MyOutputStream(ByteArrayOutputStream bos) { super(); this.bos = bos; } @Override public void write(int b) throws IOException { bos.write(b); } }
}