java -- 过滤器

过滤器

基本概念

过滤器,设计执行流程:

1.  用户访问服务器
2.  过滤器: 对Servlet请求进行拦截
3.  先进入过滤器, 过滤器处理
4.  过滤器处理完后, 在放行, 此时,请求到达Servlet/JSP
5.  Servlet处理
6.  Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户;

Javax.servlet.*;

|– interface Filter 及过滤器,过滤器核心接口

Void  init(filterConfig);    初始化方法,在服务器启动时候执行
Void  doFilter(request,response,filterChain);   过滤器拦截的业务处理方法
Void destroy();             销毁过滤器实例时候调用

|– interface FilterConfig 获取初始化参数信息

String  getInitParameter(java.lang.String name) 

Enumeration getInitParameterNames() 

|– interface FilterChain 过滤器链参数;一个个过滤器形成一个执行链;

void doFilter(ServletRequest request, ServletResponse response)  ;  执行下一个过滤器或放行

开发步骤:

1.  写一个普通java类,实现Filter接口
2.  配置过滤器

/**
 * 过滤器,测试
 * @author Jie.Yuan
 *
 */
public class HelloFilter implements Filter{

    // 创建实例--服务器启动的时候执行
    public HelloFilter(){
        System.out.println("1. 创建过滤器实例");
    }

    @Override --服务器启动的时候执行
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2. 执行过滤器初始化方法");

    // 获取过滤器在web.xml中配置的初始化参数
    String encoding = filterConfig.getInitParameter("encoding");
    System.out.println(encoding);

    // 获取过滤器在web.xml中配置的初始化参数 的名称
    Enumeration<String> enums =  filterConfig.getInitParameterNames();
    while (enums.hasMoreElements()){
        // 获取所有参数名称:encoding、path
        String name = enums.nextElement();
        // 获取名称对应的值
        String value = filterConfig.getInitParameter(name);
        System.out.println(name + "\t" + value);
    }
    }

    // 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作 ---客户请求的时候执行
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("3. 执行过滤器业务处理方法");
        // 放行 (去到Servlet)
        // 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
        chain.doFilter(request, response);

    System.out.println("5. Servlet处理完成,又回到过滤器");
    }

    @Override  服务器停止,执行所有的过滤器销毁方法
    public void destroy() {
        System.out.println("6. 销毁过滤器实例");
    }

    }

web.xml内容

<!-- 过滤器配置 
<filter>
    <!--配置初始化参数-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>path</param-name>
        <param-value>c:/...</param-value>
    </init-param>

    <filter-name>hello_filter</filter-name>
    <filter-class>cn.itcast.a_filter_hello.HelloFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hello_filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
-->

<!-- 配置第二个过滤器 -->
<!-- 演示: 拦截指定的请求 -->
<filter>
    <filter-name>hello_filter2</filter-name>
    <filter-class>cn.itcast.a_filter_hello.HelloFilter2</filter-class>
</filter>
<filter-mapping>
    <filter-name>hello_filter2</filter-name>
    <!-- 1. 拦截所有
    <url-pattern>/*</url-pattern>
     -->

     <!-- 2. 拦截指定的jsp 
     <url-pattern>/index.jsp</url-pattern>
     <url-pattern>/list.jsp</url-pattern>
     -->
     <!-- 拦截所有的jsp
     <url-pattern>*.jsp</url-pattern>
      -->
      <!-- 3. 根据servlet的内部名称拦截
      <servlet-name>IndexServlet</servlet-name>
       -->
      <!-- 拦截指定的servlet 
      <url-pattern>/index</url-pattern>
      -->

      <!-- 4. 指定拦截指定的类型 -->
      <url-pattern>/*</url-pattern>
      <!-- 拦截直接访问的请求或者重定向的资源 -->
      <dispatcher>REQUEST</dispatcher>
      <!--<dispatcher>FORWARD</dispatcher>-->
</filter-mapping>


<servlet>
    <servlet-name>IndexServlet</servlet-name>
    <servlet-class>cn.itcast.a_filter_hello.IndexServlet</servlet-class>
</servlet>
  <servlet>
    <servlet-name>ServletTest</servlet-name>
    <servlet-class>cn.itcast.a_filter_hello.ServletTest</servlet-class>
  </servlet>


<servlet-mapping>
    <servlet-name>IndexServlet</servlet-name>
    <url-pattern>/index</url-pattern>
</servlet-mapping>
  <servlet-mapping>
    <servlet-name>ServletTest</servlet-name>
    <url-pattern>/servletTest</url-pattern>
  </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

拦截

默认拦截的类型:(直接访问或者重定向)

REQUEST

拦截转发:

      <dispatcher>FORWARD</dispatcher>

拦截包含的页面(RequestDispatcher.include(/page.jsp); 对page.jsp也执行拦截)

      <dispatcher>INCLUDE</dispatcher>

拦截声明式异常(在web.xml声明了异常的处理)信息:

      <dispatcher>ERROR</dispatcher>

过滤器处理编码示例

过滤器:

public class EncodingFilter implements Filter {

// 过滤器业务处理方法:处理的公用的业务逻辑操作
@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

    // 转型
    final HttpServletRequest request = (HttpServletRequest) req;    
    HttpServletResponse response = (HttpServletResponse) res;

    // 一、处理公用业务
    request.setCharacterEncoding("UTF-8");                  // POST提交有效
    response.setContentType("text/html;charset=UTF-8");

    /*
     * 出现GET中文乱码,是因为在request.getParameter方法内部没有进行提交方式判断并处理。
     * String name = request.getParameter("userName");
     * 
     * 解决:对指定接口的某一个方法进行功能扩展,可以使用代理!
     *      对request对象(目标对象),创建代理对象!
     */
    HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
            request.getClass().getClassLoader(),        // 指定当前使用的类加载器
            new Class[]{HttpServletRequest.class},      // 对目标对象实现的接口类型
            new InvocationHandler() {                   // 事件处理器
                @Override
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    // 定义方法返回值
                    Object returnValue = null;
                    // 获取方法名
                    String methodName = method.getName();
                    // 判断:对getParameter方法进行GET提交中文处理
                    if ("getParameter".equals(methodName)) {

                        // 获取请求数据值【 <input type="text" name="userName">】
                        String value = request.getParameter(args[0].toString());    // 调用目标对象的方法

                        // 获取提交方式
                        String methodSubmit = request.getMethod(); // 直接调用目标对象的方法

                        // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
                        if ("GET".equals(methodSubmit)) {
                            if (value != null && !"".equals(value.trim())){
                                // 处理GET中文
                                value = new String(value.getBytes("ISO8859-1"),"UTF-8");
                            }
                        } 
                        return value;
                    }
                    else {
                        // 执行request对象的其他方法
                        returnValue = method.invoke(request, args);
                    }

                    return returnValue;
                }
            });

    // 二、放行 (执行下一个过滤器或者servlet)
    chain.doFilter(proxy, response);        // 传入代理对象
}

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

}

@Override
public void destroy() {

}
}

过滤器配置:
<!-- 编码处理过滤器配置 -->
<filter>
    <filter-name>encoding</filter-name>
    <filter-class>cn.itcast.a_loginFilter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


Servlet:
public class LoginServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // 获取请求数据 
    String name = request.getParameter("userName");
    System.out.println("用户:" + name);
}

登陆权限判断

登陆, 提交到登陆Servlet处理其业务!

-登陆成功, 跳转到首页,显示欢迎信息 + 列表信息

-登陆失败,跳转到登陆!

 http://localhost:8080/emp_sys/login.jsp   可以直接访问
http://localhost:8080/emp_sys/login      可以直接访问
http://localhost:8080/emp_sys/index   不能直接访问
http://localhost:8080/emp_sys/list.jsp   不能直接访问


public class LoginFilter implements Filter {

private String uri;

 分析:

    1. 先指定放行的资源,哪些资源不需要拦截:
          login.jsp   +    /login  (request对象可以获取)
    2. 获取session,从session中获取登陆用户
    3. 判断是否为空:
          为空, 说明没有登陆, 跳转到登陆
           不为空, 已经登陆,放行!

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

    //0. 转换
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    //1. 获取请求资源,截取  
    String uri = request.getRequestURI();   // /emp_sys/login.jsp
    // 截取 【login.jsp或login】
    String requestPath = uri.substring(uri.lastIndexOf("/") + 1, uri.length());  

    //2. 判断: 先放行一些资源:/login.jsp、/login
    if ("login".equals(requestPath) || "login.jsp".equals(requestPath)) {
        // 放行
        chain.doFilter(request, response);
    }
    else {
        //3. 对其他资源进行拦截
        //3.1 先获取Session、获取session中的登陆用户(loginInfo)
        HttpSession session = request.getSession(false);
        // 判断
        if (session != null) {

            Object obj = session.getAttribute("loginInfo");

            //3.2如果获取的内容不为空,说明已经登陆,放行
            if (obj != null) {
                // 放行
                chain.doFilter(request, response);
            } else {
                //3.3如果获取的内容为空,说明没有登陆; 跳转到登陆
                uri = "/login.jsp";
            }

        } else {
            // 肯定没有登陆
            uri = "/login.jsp";
        }
        request.getRequestDispatcher(uri).forward(request, response);
    }
}

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

@Override
public void destroy() {
}

}

web.xml

<!-- 登陆验证过滤器 -->
<filter>
    <filter-name>loginFilter</filter-name>
    <filter-class>cn.itcast.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>loginFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.itcast.servlet.LoginServlet</servlet-class>
</servlet>
<servlet>
    <servlet-name>IndexServlet</servlet-name>
    <servlet-class>cn.itcast.servlet.IndexServlet</servlet-class>
</servlet>


<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>IndexServlet</servlet-name>
    <url-pattern>/index</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

猜你喜欢

转载自blog.csdn.net/qq_17503037/article/details/80455410