• Filter的常见应用


    1.字符编码过滤器

    实现功能,在a.jsp中填写用户名提交到b.jsp,在b.jsp中读取参数名。

    a.jsp

    <body>
      <form action="encoding/b.jsp" method="post">
        name:<input type="text" name="username"/>
        <input type="submit" value="Submit"/>
      </form>
    </body>
    

    b.jsp

    <body>
    <% request.setCharacterEncoding("UTF-8");%>
      hello:${param.username}
    </body>
    

    若需要读取参数的页面太多,需要在每一个页面都添加<% request.setCharacterEncoding("UTF-8");%>,该方法行不通。字符编码过滤器通过配置参数encoding指明使用何种字符编码,以处理Html Form请求参数的中文问题。

    HttpFilter.java

    package com.javaweb.Filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public abstract class HttpFilter implements Filter {
    	@Override
    	public void destroy() { }
        /*
         * 原生的doFilter方法,在方法内部把ServletRequest和ServletResponse转为了HttpServletRequest和HttpServletResponse,
         * 并调用了doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain)方法。
         * 若编写Filter的过滤方法不建议直接继承该方法,而建议继承doFilter(HttpServletRequest request,HttpServletResponse response,
         * FilterChain filterchain)方法。
         * */
    	@Override
    	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterchain)
    			throws IOException, ServletException {
    		HttpServletRequest request=(HttpServletRequest) req;
    		HttpServletResponse response=(HttpServletResponse) resp;
    	    doFilter(request,response,filterchain);
    	}
    	//抽象方法,为Http请求定制必须实现的方法。
    	public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain) throws IOException, ServletException;
        private FilterConfig filterconfig;
        //不建议子类直接覆盖,若直接覆盖,将可能会导致filterConfig成员变量初始化失败。
    	@Override
    	public void init(FilterConfig filterconfig) throws ServletException {
    		this.filterconfig =filterconfig;
    		init();
    	}
    	//供子类继承的初始化方法,可以通过getFilterConfig()获取FilterConfig对象。
        public void init(){}
        //直接返回init(ServletConfig)的ServletConfig对象。
        public FilterConfig getFilterConfig(){
        	return filterconfig;
        }
    }
    

    encodingFilter.java

    package com.javaweb.Filter;
    import java.io.IOException;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.javaweb.Filter.HttpFilter;
    
    public class encodingFilter extends HttpFilter {
    
    	@Override
    	public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterchain)
    			throws IOException, ServletException {
    		//2.指定请求的字符编码为1中读取的字符编码
            request.setCharacterEncoding(encoding);
            //3.调用chain.doFile()方法放行请求
            filterchain.doFilter(request,response);
    	}
    	private String encoding;
    	public void init(){
    		//1.读取配置文件web.xml中的字符编码方式
    		encoding=getFilterConfig().getServletContext().getInitParameter("encoding");
    	}
    }
    

    在web.xml中进行配置,首先指定当前页的字符编码:

    <context-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </context-param>
    

    配置encodingFilter,

      <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>com.javaweb.Filter.encodingFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/encoding/*</url-pattern>
      </filter-mapping>
    

    这样,不用在b.jsp页面指定<% request.setCharacterEncoding("UTF-8");%>也不会出现输入中文的乱码问题。

    2.检测用户是否登录过的过滤器

    系统中的某些页面只有在正常登录后才可以使用,用户请求这些页面时要检查session中有无该用户的信息,但在所有的页面加上session的判断相当麻烦。因此需要重新编写一个用于检测用户是否登录的过滤器,如果用户未登录,则重定向到指定的登录页面。

    示例代码:

    a.jsp

      <body>
        <h4>AAA page</h4>
        <a href="login/list.jsp">return list...</a>
      </body>
    

    b.jsp

      <body>
        <h4>BBB page</h4>
        <a href="login/list.jsp">return list...</a>
      </body>
    

    c.jsp

      <body>
        <h4>CCC page</h4>
        <a href="login/list.jsp">return list...</a>
      </body>
    

    d.jsp

      <body>
        <h4>DDD page</h4>
        <a href="login/list.jsp">return list...</a>
      </body>
    

    e.jsp

      <body>
        <h4>EEE page</h4>
        <a href="login/list.jsp">return list...</a>
      </body>
    

    list.jsp

      <body>
        <a href="login/a.jsp">AAA</a>
        <br><br>
        <a href="login/b.jsp">BBB</a>
        <br><br>
        <a href="login/c.jsp">CCC</a>
        <br><br>
        <a href="login/d.jsp">DDD</a>
        <br><br>
        <a href="login/e.jsp">EEE</a>
        <br><br>
      </body>
    

    login.jsp

      <body>
      <form action="login/doLogin.jsp" method="post">
        username:<input type="text" name="username"/>
        <input type="submit" value="Submit"/>
      </form> 
      </body>
    

    doLogin.jsp

      <body>
        <%
        String username=request.getParameter("username");
        if(username!=null){
            session.setAttribute(application.getInitParameter("sessionKey"),username);
            response.sendRedirect("list.jsp");
        }else{
            response.sendRedirect("login.jsp");
        }
        
         %>
      </body>
    

    loginFilter.java

    package com.javaweb.Filter;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.javaweb.Filter.HttpFilter;
    
    public class loginFilter extends HttpFilter {
        String sessionKey;
        String redirectUrl;
        String uncheckedUrls;
    	@Override
    	public void init() {
    		ServletContext servletcontext=getFilterConfig().getServletContext();
    		sessionKey=servletcontext.getInitParameter("sessionKey");
    		redirectUrl=servletcontext.getInitParameter("redirectPage");
    		uncheckedUrls=servletcontext.getInitParameter("uncheckedPage");
    		
    	}
        
    	@Override
    	public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterchain)
    			throws IOException, ServletException {
    		//b.jsp    c.jsp   d.jsp   ...
    		String servletPath=request.getServletPath();
    		//检查uncheckedUrls是否包含请求的URL,若包含,放行
    		List<String> Urls=Arrays.asList(uncheckedUrls.split(","));
    		if (Urls.contains(servletPath)){
    			filterchain.doFilter(request, response);
    			return;
    		}
    		//从sessionKey中检查是否包含sessionKey对应的值,若值不存在,则重定向到redirectUrl
    		Object user=request.getSession().getAttribute(sessionKey);
    		if (user==null){
    			response.sendRedirect(request.getContextPath()+redirectUrl);
    			return;
    		}
    		//若存在,则放行
    		filterchain.doFilter(request, response);
    		
    	}
    
    }
    

    在web.xml中进行配置:

      <context-param>
        <param-name>redirectPage</param-name>
        <param-value>/login/login.jsp</param-value>
      </context-param>
      <context-param>
        <param-name>uncheckedPage</param-name>
        <param-value>/login/a.jsp,/login/doLogin.jsp,/login/list.jsp,/login/login.jsp</param-value>
      </context-param>
      <context-param>
        <param-name>sessionKey</param-name>
        <param-value>sessionValue</param-value>
      </context-param>
      <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>com.javaweb.Filter.loginFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>loginFilter</filter-name>
        <url-pattern>/login/*</url-pattern>
      </filter-mapping>

    AAA页面不需要登录即可访问,

     点击BBB(及之后的)超链接时,跳转到登录页面:

    填写登录名之后再访问BBB,可以跳转到BBB页面:

  • 相关阅读:
    日期格式,Popup的使用方法,RenderTransform与LayoutTransform的区别
    Status 网络
    以太坊: RLP 编码原理
    Merkle Patricia Tree 梅克尔帕特里夏树(MPT)详细介绍
    【转】货币的未来取决于打破关于货币历史的虚构谎言
    区块链上的保险
    Trustlines Network:以太坊上实现 Ripple 瑞波协议
    通过 BTC Relay 来实现链与链的连接
    PoW模式下交易平均要35秒,为什么为拥堵
    使用以太坊和 Metamask 再也不需要输入密码
  • 原文地址:https://www.cnblogs.com/naihuangbao/p/9937478.html
Copyright © 2020-2023  润新知