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()); } }
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>
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 } }
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中移除!"); } }
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()"); } }
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")); }
动态国际化
//日期 @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); }
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>