Java Web高级编程(三)

动用过滤器立异应用程序

一、过滤器的目标

过滤器是足以阻止访问资源的央求、资源的响应或者同时阻止两者的选取组件。过滤器可以检测和修改请求和响应,同时也足以拒绝、重定向或转化呼吁。javax.servlet.Filter接口实现了过滤器技术,使用HttpServletRequest和HttpServletResponse。过滤器可以在布局描述符中以以编程的法子宣示,它们能够有开端化参数并且可以访问ServletContext。

日志过滤器

在应用程序开发中,需要记录所有应用程序的伸手和各个请求的结果(状态码,长度等其他消息)。平常Web容器提供了请求日志的体制,但只要急需在伸手日志中显示出有些有意识的信息,可以动用过滤记录请求。

表达过滤器

假定急需确保唯有授权用户才方可访问应用程序,平日能够检查各类请求的信息,保证用户已登录,过滤器可以经过将申明和授权操作集中到一个岗位的不二法门使办事变得简单。

缩减和加密过滤器

存在着网络带宽有限而CPU资源富集的情况,日常在多少传输此前对数码举行压缩。过滤器可以在收到请求时,请求保持不变,但在响应重临给用户时,使用过滤器可以减去相应对象。

错误处理过滤器

对于Web用用程序而言,出现谬误,是一个HTTP响应代码500,一般还会陪伴着一个无独有偶的HTML页面,写着“Internal
Server
Error”以及一些确诊信息。对于在地面运行的应用程序对开发者是有效的,不过对于远程的应用程序来说是不必要的。需要经过过滤器给用户呈现出更加友好的和通用的错误处理页面,并记下必要的错误音信。

二、创造、讲明和照耀过滤器

创办过滤器就是贯彻Filter接口一样,过滤器在起头化的时候将调用init方法,他得以访问过滤器的安排起初化参数和ServletContext。当呼吁进入到过滤器中,doFilter方法将会被调用,它提供了对ServletRequest、ServletResponse和FilterChain对象的拜会。在doFilter中,可以拒绝请求或者调用FilterChain对象的doFilter方法,能够打包请求和响应对象。

过滤器链

即便唯有一个Servlet可以拍卖请求,然则足以接纳过多的过滤拦截请求。在过滤器链中每一个过滤器接受进入的哀告并将它传递到下一个过滤链中,直到所有匹配的过滤器都处理到位,最后再将它传到Servlet中。调用FilterChain.doFilter()将触发过滤器链的无休止推行。假使当前的过滤器没有调用FilterChain.doFilter(),将把控制权重回值Servlet容器中。

映射到URL模式和Servlet名称

同Servlet一样,过滤器可以被映射到URL形式,这会控制哪些或如何过滤器将截留某个请求。任何匹配某个过滤器的URL情势的伸手在被匹配的Servlet处理往日将率先进入该过滤器,通过利用URL情势,不仅可以阻挡Servlet请求,还足以阻挡任何资源。

Java,只是当现在曾经有两个URL已经映射到Servlet上,并且希望某些过滤器映射到这些URL上。与映射到URL上反而,可以将这么些过滤器映射到一个或四个Servlet名称上。

1.在部署描述符中使用<filter>和<filter-mapping>元素:

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.AnyRequestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在宣称了过滤器之后,能够将它映射到自由数目标URL或Servlet名称。当然过滤器URL映射还是能够蕴涵通配符。

2.运用注脚申明和照耀过滤器

@WebFilter{
    filterName = "myFilter",
    urlPatterns = {"/foo","/bar/*"},
    serVletNames = {"myServlet"},
    dispatcherTypes = {DispatcherType.REQUEST,         
    DispatcherType.ASYNC}    
}

但是不可以对对过滤器链上的过滤器举办排序

三、过滤器排序

过滤器的次第决定了过滤器在过滤器链中出现的岗位,这里将会利用安排描述符来举办配置,因为注明无法举办排序配置。

URL模式映射和Servlet名称映射,匹配请求的过滤器将服从它们出现在配置描述符或者编程式配置中的顺序添加到过滤器链中,然则需要小心URL映射的过滤器优先级比Servlet名称映射到的过滤器高,由URL形式匹配的过滤器总是现身在有Servlet名称匹配的过滤器此前。

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.FilterA</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterB</filter-name>
        <filter-class>com.wrox.FilterB</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterB</filter-name>
        <url-pattern>/servletTwo</url-pattern>
        <url-pattern>/servletThree</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterC</filter-name>
        <filter-class>com.wrox.FilterC</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterC</filter-name>
        <url-pattern>/servletTwo</url-pattern>
    </filter-mapping>

这是一个filter的实例:

这是拍卖中的第一个过滤器,它将记录处理请求的时间,并记下所有访问应用程序的呼吁音讯——IP地址、时间戳、请求方法等信息,finally块中是日记的操作。

public class RequestLogFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException
    {
        Instant time = Instant.now();
        StopWatch timer = new StopWatch();
        try
        {
            timer.start();
            chain.doFilter(request, response);
        }
        finally
        {
            timer.stop();
            HttpServletRequest in = (HttpServletRequest)request;
            HttpServletResponse out = (HttpServletResponse)response;
            String length = out.getHeader("Content-Length");
            if(length == null || length.length() == 0)
                length = "-";
            System.out.println(in.getRemoteAddr() + " - - [" + time + "]" +
                    " \"" + in.getMethod() + " " + in.getRequestURI() + " " +
                    in.getProtocol() + "\" " + out.getStatus() + " " + length +
                    " " + timer);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }
}

 

相关文章