监听器

监听器: 主要是用来监听特定对象的创建或销毁、属性的变化的!
是一个实现特定接口的普通java类!

Servlet中哪些对象需要监听?

request / session / servletContext
分别对应的是request监听器、session相关监听器、servletContext监听器

监听器接口:

生命周期监听器

一、监听对象创建/销毁的监听器接口

Interface ServletRequestListener     监听request对象的创建或销毁
Interface HttpSessionListener        监听session对象的创建或销毁
Interface ServletContextListener     监听servletContext对象的创建或销毁

监听request对象的创建或销毁

public class MyRequestListener implements ServletRequestListener{

// 对象销毁
@Override
public void requestDestroyed(ServletRequestEvent sre) {
    // 获取request中存放的数据
    Object obj = sre.getServletRequest().getAttribute("cn");
    System.out.println(obj);
    System.out.println("MyRequestListener.requestDestroyed()");
}

// 对象创建
@Override
public void requestInitialized(ServletRequestEvent sre) {
    System.out.println("MyRequestListener.requestInitialized()");
}
}

Web.xml

<!-- 监听request对象创建、销毁 -->
<listener>
    <listener-class>cn.itcast.a_life.MyRequestListener</listener-class>
</listener>

监听ServletContext对象创建或销毁

ServletContext对象是在服务器打开和关闭的时候创建和销毁的

public class MyServletContextListener implements ServletContextListener{

@Override
public void contextDestroyed(ServletContextEvent sce) {
    System.out.println("MyServletContextListener.contextDestroyed()");
}

@Override
public void contextInitialized(ServletContextEvent sce) {
    System.out.println("1..........MyServletContextListener.contextInitialized()");
}

}

监听Session对象创建、销毁

Session对象在用户关闭浏览器时并不马上销毁,而是不能使用,默认session存在时间30分钟,时间过期后session销毁

public class MySessionListener implements HttpSessionListener{

// 创建
@Override
public void sessionCreated(HttpSessionEvent se) {
    System.out.println("MySessionListener.sessionCreated()");
}

// 销毁
@Override
public void sessionDestroyed(HttpSessionEvent se) {
    System.out.println("MySessionListener.sessionDestroyed()");
}

}

web.xml内容

<!-- session的最大活跃时间 -->
<session-config>
    <session-timeout>60</session-timeout>
</session-config>

<!-- 监听request对象创建、销毁 -->
<listener>
    <listener-class>cn.itcast.a_life.MyRequestListener</listener-class>
</listener>
<!-- 监听session对象创建、销毁 -->
<listener>
    <listener-class>cn.itcast.a_life.MySessionListener</listener-class>
</listener>

<!-- 监听servletContext对象创建、销毁 -->
<listener>
    <listener-class>cn.itcast.a_life.MyServletContextListener</listener-class>
</listener>

<!-- 属性监听器 -->
<listener>
    <listener-class>cn.itcast.b_attr.MySessionAttrListener</listener-class>
</listener>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

属性监听器

二、监听对象属性的变化

Interface ServletRequestAttributeListener 监听request对象属性变化: 添加、移除、修改
Interface HttpSessionAttributeListener    监听session对象属性变化: 添加、移除、修改
Interface ServletContextAttributeListener  监听servletContext对象属性变化

监听session对象属性的变化

public class MySessionAttrListener implements HttpSessionAttributeListener {

// 属性添加
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
    // 先获取session对象
    HttpSession session = se.getSession();
    // 获取添加的属性
    Object obj = session.getAttribute("userName");
    // 测试
    System.out.println("添加的属性:" + obj);
}

// 属性移除
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
    System.out.println("属性移除");
}

// 属性被替换
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
    // 获取sesison对象
    HttpSession session = se.getSession();

    // 获取替换前的值
    Object old = se.getValue();
    System.out.println("原来的值:" + old);

    // 获取新值
    Object obj_new = session.getAttribute("userName");
    System.out.println("新值:" + obj_new);

}

}

session相关监听器

Interface HttpSessionBindingListener   监听对象绑定到session上的事件   
Interface HttpSessionActivationListener(了解) 监听session序列化及反序列化的事件

监听此对象绑定到session上的过程,需要实现session特定接口

监听对象绑定/解除绑定到sesison上的事件!

步骤:

对象实现接口; 再把对象绑定/解除绑定到session上就会触发监听代码。

作用:(上线提醒!)

这个session监听器,和上面的声明周期、属性监听器区别?

-- 不用再web.xml配置
- 因为监听的对象是自己创建的对象,不是服务器对象!

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
@Override
public void valueBound(HttpSessionBindingEvent event) {
    System.out.println("Admin对象已经放入session");
}
// 对象从session中移除
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
    System.out.println("Admin对象从session中移除!");
}
}

国际化

软件的国际化:

软件
    中国: 显示中文,以及服务符合中国习惯的文本字符串!
                         1999-09-09
    美国: 显示英文,以及服务符合他国习惯的文本字符串!
这种软件,就叫国际化的软件!

本地化 Locale

public class App {

@Test
//1. 本地化对象:Locale
// 封装语言、国家信息的对象,有java.util提供
public void testLocale() throws Exception {
    // 模拟中国语言等环境
    //Locale locale = Locale.CHINA;
    Locale locale = Locale.getDefault();            // 当前系统默认的语言环境
    System.out.println(locale.getCountry());        // CN  国家的简称
    System.out.println(locale.getDisplayCountry()); // 国家名称
    System.out.println(locale.getLanguage());       // zh 语言简称

    // 模拟美国国家
    Locale l_us = Locale.US;
    System.out.println(l_us.getCountry());
    System.out.println(l_us.getDisplayCountry());
}
}

静态数据国际化

  1. 存储所有国家显示的文本的字符串

a) 文件: properties

b) 命名: 基础名语言简称国家简称.properties

例如:msg_zh_CN.properties 存储所有中文
Msg_en_US.properties 存储所有英文

  1. 程序中获取
    ResourceBundle类,可以读取国际化的资源文件!

    // 国际化 - 静态数据
    @Test
    public void testI18N() throws Exception {

    // 中文语言环境
    Locale locale = Locale.US;
    
    // 创建工具类对象ResourceBundle
    ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.f_i18n.msg", locale);
    // 根据key获取配置文件中的值
    System.out.println(bundle.getString("hello"));
    System.out.println(bundle.getString("username"));
    System.out.println(bundle.getString("pwd"));
    

    }

msg_ en _US.properties内容

hello=Hello
username=User Name
pwd=Password
title=Login Page
submit=Submit \!

msg.properties内容(默认当前语言环境的命名,最好写全)

hello=\u4F60\u597D
username=\u7528\u6237\u540D
pwd=\u5BC6\u7801
title=\u767B\u9646\u9875\u9762
submit=\ \u767B\u9646 

动态文本国际化

中文:1987-09-19 ¥1000

英文: Sep/09 1987 $100

 数值,货币,时间,日期等数据由于可能在程序运行时动态产生,所以无法像文字一样简单地将它们从应用程序中分离出来,而是需要特殊处理。Java 中提供了解决这些问题的 API 类(位于 java.util 包和 java.text 包中)

// 国际化 - 动态文本 - 0. 概述
@Test
public void testI18N2() throws Exception {
    // 国际化货币
    NumberFormat.getCurrencyInstance();
    // 国际化数字
    NumberFormat.getNumberInstance();
    // 国际化百分比
    NumberFormat.getPercentInstance();  
    // 国际化日期
    //DateFormat.getDateTimeInstance(dateStyle, timeStyle, aLocale)
}

// 国际化 - 动态文本 - 1. 国际化货币
@Test
public void testI18N3() throws Exception {
    // 模拟语言环境
    Locale locale = Locale.CHINA;
    // 数据准备
    double number = 100;
    // 工具类
    NumberFormat nf = NumberFormat.getCurrencyInstance(locale);
    // 国际化货币
    String m = nf.format(number);
    // 测试
    System.out.println(m);
}

//面试题:  代码计算:  $100 * 10  
@Test
public void eg() throws Exception {
    String str = "$100";
    int num = 10;

    // 1. 分析str值是哪一国家的货币
    Locale us = Locale.US;
    // 2. 国际化工具类
    NumberFormat nf = NumberFormat.getCurrencyInstance(us);
    // 3. 解析str国币
    Number n = nf.parse(str);

    System.out.println(n.intValue() * num);
}

// 国际化 - 动态文本 - 2. 国际化数值
@Test
public void testI18N4() throws Exception {
    // 模拟语言环境
    Locale locale = Locale.CHINA;
    NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
    String str = nf.format(1000000000);
    System.out.println(str);
}

// 国际化 - 动态文本 - 3. 国际化日期
/*
 * 日期
 *    FULL   2015年3月4日 星期三
 *    LONG   2015年3月4日
 *    FULL   2015年3月4日 星期三
 *    MEDIUM 2015-3-4
 *    SHORT  15-3-4
 *    
 * 时间
 *    FULL   下午04时31分59秒 CST
 *    LONG   下午04时32分37秒
 *    MEDIUM 16:33:00
 *    SHORT  下午4:33
 *    
 * 
 */
@Test
public void testI18N5() throws Exception {

    // 日期格式
    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);
}

// 面试2: 请将时间值:09-11-28 上午10时25分39秒 CST,反向解析成一个date对象。
@Test
public void eg2() throws Exception {
    String str = "09-11-28 上午10时25分39秒 CST";
    // 创建DateFormat工具类,国际化日期
    DateFormat df = DateFormat.getDateTimeInstance(
            DateFormat.SHORT, DateFormat.FULL, Locale.getDefault());
    Date d = df.parse(str);

    System.out.println(d);
}

Jsp页面国际化 – 使用jstl标签

JSTL标签:

核心标签库
国际化与格式化标签库
数据库标签库(没用)
函数库

<fmt:setLocale value=""/>        设置本地化对象
<fmt:setBundle basename=""/>     设置工具类
<fmt:message></fmt:message>     显示国际化文本
格式化数值
<fmt:formatNumber pattern="#.##" value="100.99"></fmt:formatNumber>
格式化日期:
<fmt:formatDate pattern="yyyy-MM-dd" value="${date}"/>

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--引入jstl国际化与格式化标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<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>


    <!-- 
    格式化金额 
        格式: 0.00   保留2为小数,会自动补0
             #.##  保留2为小数,不自动补0(四舍五入)
-->
<fmt:formatNumber pattern="#.##" value="100.99"></fmt:formatNumber>

<!-- 格式化日期 -->
<fmt:formatDate pattern="yyyy-MM-dd" value="<%=new Date() %>"/>
  </body>
</html>
posted on 2018-05-30 18:44  NE_STOP  阅读(0)  评论(0编辑  收藏  举报  来源