• java深入探究09-Filter,Listener,国际化


    1.Filter过滤器

      1)为是么有过滤器

        开发项目中经常遇到直接登录主页面要判断用户是否合法,这类代码比较重复,可以通过过滤器来解决

      2)过滤器原理生命周期

        服务器创建过滤器对象-》一个执行init()方法-》用户请求-》执行第一个过滤器-》执行第二个过滤器-》到达目标地址-》浏览器关闭过滤器销毁

      3)过滤器语法

        Filter接口:三个主要方法

          init(FilterConfig):初始化方法,service()服务启动时执行 

          doFilter(request,response,FilterChain chain);过滤器拦截的业务处理方法

          destroy();  销毁过滤器实例时调用

          

          其中:filterConfig:获取初始化参数信息;getInitParameter("");getInitParameterName()

             chain:过滤器参数,一个个过滤器形成一个执行链

                作用:执行下一个过滤器或放行

      4)部署过滤器

        1.创建类继承Filter接口

           实现3个方法

    public class HelloFilter implements Filter{
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
            System.out.println("helloFilter销毁了!");
        }
    
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1,
                FilterChain arg2) throws IOException, ServletException {
            // TODO Auto-generated method stub
            System.out.println("HelloFilter正在过滤");
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
            // TODO Auto-generated method stub
            System.out.println("过滤器初始化开始");
            String name=arg0.getInitParameter("name");
            System.out.println("name的值:"+name);
            Enumeration<String> names=arg0.getInitParameterNames();
            while(names.hasMoreElements()){
                System.out.println("初始化参数"+names.nextElement());
            }
        }
    View Code

        2.配置xml

          <filter></filter>子成员配置可以靠Myeclipse提示

     <filter>
            <filter-name>HelloFilter</filter-name>
            <filter-class>filter.HelloFilter</filter-class>
            <init-param>
                <param-name>name</param-name>
                <param-value>小平</param-value>
            </init-param>
            <init-param>
                <param-name>age</param-name>
                <param-value>23</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>HelloFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    View Code

      5)案例:过滤器编码统一处理

    package filter;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    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;
    
    /**
     * 编码过滤对登录中的处理
     * @author Administrator
     *
     */
    public class EncodingFilter implements Filter{
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
            System.out.println("EncodingFilter销毁了");
        }
    
        @Override
        public void doFilter(final ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            // TODO Auto-generated method stub
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            chain.doFilter(request, response);
            
            //这里出现一个情况,post时不会乱码,但get请求时会乱码
            //原因:get请求post请求发送信息方式不一样,get信息是在url中的可见都是乱码因为这里ISO编码格式
            //解决方式:在request.getParameter()时,加个判断当时Get请求时另作处理;
                    //这里的情况就是想要requeset接口的特定方法进行功能扩展用到”代理“
            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();
                            //判断当方法微微GET时要处理些
                            if("getParameter".equals(methodName)){
                                // 获取请求数据值【 <input type="text" name="userName">】
                                String value = request.getParameter(args[0].toString());    // 调用目标对象的方法
                                
                                // 获取提交方式
                                String methodSubmit = ((HttpServletRequest) request).getMethod(); // 直接调用目标对象的方法
                                
                                // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
                                if ("GET".equals(methodSubmit)) {
                                    if (value != null && !"".equals(value.trim())){
                                        // 处理GET中文
                                        value = new String(value.getBytes("ISO8859-1"),"UTF-8");
                                    }
                                } 
                                
                            }else{
                                // 执行request对象的其他方法
                                returnValue = method.invoke(request, args);
                            }
                            return returnValue;
                        }
                    });
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // TODO Auto-generated method stub
            
        }
    
    }
    View Code

    2.Listener监听器

      1)定义

        监听特定对象的创建销毁属性变化

      2)Servlet中哪些对象需要监听

        request,session,ServletContext三对象(这些有系统自己创建添加监听器时需要配置xml);自己的对象就不需要配置

      3)主要API

        1.监听对象创建/销毁的监听接口

          ServletRequestListener  监听request对象的创建销毁

          HttpSessionListener    监听session

          ServletContextListener  监听servletCOntext对象的创建或销毁

        2.监听对象属性的变化

          ServletRequestAttrbuteListener

          HttpSessionAttributeListener    

          ServletContextAttributeListener  

        3.session相关监听器

          HttpSessionBindingListener:监听对象绑定到session上的事件

          HttpSessionActivationListener:监听session序列及反序列

          例子:这个不需要配置web.xml

    package cn.itcast.c_session;
    
    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionBindingListener;
    
    /**
     * 监听此对象绑定到session上的过程,需要实现session特定接口
     * @author Jie.Yuan
     *
     */
    public class Admin implements HttpSessionBindingListener {
    
        private int id;
        private String name;
        
        public Admin() {
            super();
        }
        public Admin(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        
        
        // 构造函数
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        // 对象放入session
    
        public void valueBound(HttpSessionBindingEvent event) {
            System.out.println("Admin对象已经放入session");
        }
        // 对象从session中移除
    
        public void valueUnbound(HttpSessionBindingEvent event) {
            System.out.println("Admin对象从session中移除!");
        }
        
    }
    View Code

      4)部署步骤

        写一个普通类继承相关接口-》系统创建对象配置xml 

      5)例子:

        1.MyRequestListener

    /**
     *  监听request对象的创建或销毁
     * @author Jie.Yuan
     *
     */
    public class MyRequestListener implements ServletRequestListener{
    
        // 对象销毁
        
        public void requestDestroyed(ServletRequestEvent sre) {
            // 获取request中存放的数据
            Object obj = sre.getServletRequest().getAttribute("cn");
            System.out.println(obj);
            System.out.println("MyRequestListener.requestDestroyed()");
        }
    
        // 对象创建
    
        public void requestInitialized(ServletRequestEvent sre) {
            System.out.println("MyRequestListener.requestInitialized()");
        }
    }
    View Code

        2.配置:简简单单配置就好了

    <listener> 
      <listener-class>cn.listen.MyListener</listener-class>
    </listener> 

    3.国际化:i18n:internationlization

      1)不同国家显示不同的语言国际化软件

      2)实现方式:

        1.软件中存储特定的字符串;2.软件识别当前哪种语言(Locale)

      3)分为静态国际化,动态国际化

    静态国际化

    //国际化-静态数据
        @Test
        public void testI18N(){
            //中文语言环境
            Locale local=Locale.US;
            //创建工具对象ResourceBundle
            ResourceBundle bundle=ResourceBundle.getBundle("local.msg",local);
            //根据key获取配置文件中的值
            System.out.println(bundle.getString("hello"));
            System.out.println(bundle.getString("username"));
        }
    View Code

    动态国际化

        //日期
        @Test
        public void testI18N4(){
            // 日期格式
            int dateStyle = DateFormat.SHORT;
            // 时间格式
            int timeStyle = DateFormat.SHORT;
            //
            DateFormat df=DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.CHINA);
            //获得数据
            String date=df.format(new Date());
            System.out.println(date);
            
        }
        //讲09-11-28 上午10时25分39秒 CST,反向解析成一个date对象
        @Test
        public void testI18N5() throws Exception{
            String str="09-11-28 上午10时25分39秒 CST";
            
            DateFormat df=DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.FULL , Locale.CHINA);
            Date d=df.parse(str);
            System.out.println(d);
        }
    View Code

       4)Jsp页面国际化-使用jstl标签

        JSTL标签有:核心标签库,国际化和格式化标签库,数据库标签(没用),函数库

        <fmt:setLocale value=""/> 设置本地化对象

        <fmt:setBundle basename=""/>设置工具类(RourseBunlde)

        <fmt:message></fmt:message> 显示国际化文本

        格式化数值

        <fmt:formatNumber pattern="#,##" value="10.99"></fmt:formatNumbr>

        格式化日期

        <fmt:formatDate pattern="yyyy-MM-dd" value=${date}>

        例子:

    1.设置本地化对象
    <fmt:setLocale value="${pageContext.request.locale}"/>
    2.设置工具类:
    <fmt:setBundle basename="cn.itcast.f_i18n.msg" var="bundle"/>
    3.shezhi wenben guojihua
    <fmt:message key="title" bundle="${bundle}"></fmt:message>
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%--引入jstl国际化与格式化标签库 --%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
          <!-- 一、设置本地化对象 -->
          <fmt:setLocale value="${pageContext.request.locale}"/>
          <!-- 二、设置工具类 -->
          <fmt:setBundle basename="cn.itcast.f_i18n.msg" var="bundle"/>
    
        <title><fmt:message key="title" bundle="${bundle}"></fmt:message></title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      
      <body>
      <form name="frmLogin" action="${pageContext.request.contextPath }/admin?method=login" method="post">
          <table align="center" border="1">
              <tr>
                  <td><fmt:message key="username" bundle="${bundle}"></fmt:message></td>
                  <td>
                      <input type="text" name="userName">
                  </td>
              </tr>
              <tr>
                  <td><fmt:message key="pwd" bundle="${bundle}"></fmt:message></td>
                  <td>
                      <input type="password" name="pwd">
                  </td>
              </tr>
              <tr>
                  <td>
                      <input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>">
                  </td>
              </tr>
          </table>
      </form>
      </body>
    </html>
    View Code
  • 相关阅读:
    「AHOI / HNOI2017」单旋
    【CQOI2012】局部极小值
    【CQOI2011】放棋子
    【gdoi2018 day2】第二题 滑稽子图
    【JSOI2018】潜入行动
    在vue中获取不到canvas对象? 两种解决办法。
    数据可视化echart
    在vue中使用高德地图开发,以及AMap的引入?
    mac 常使用的一些小技巧
    form编码方式application/x-www-form-urlencoded和multipart/form-data的区别?
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/6867124.html
Copyright © 2020-2023  润新知