J2EE进阶之自定义标签,JSTL标签,国际化 十四

来源:互联网 发布:java 获取文件路径 编辑:程序博客网 时间:2024/05/24 02:30

自定义标签,JSTL标签,web国际化

一、自定义标签

自定义标签主要用于移除Jsp页面中的java代码。

使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤:
1:编写一个实现Tag接口的Java类(标签处理器类)。
2:编写标签库描述符(tld)文件,在tld文件中把标签处理器类进行描述。

1自定义标签的开发步骤

1:编写一个类,直接或间接地实现javax.servlet.jsp.tagext.SimpleTag。一般继承javax.servlet.jsp.tagext.SimpleTagSupport。

2:在WEB-INF目录下建立一个扩展名是tld的xml文件。

tld的属性直接拷贝一般,在 E:\apache-tomcat-7.0.55\webapps\examples 下搜索tld文件直接拷贝属性:

然后在自己tld中写配置文件

3:使用:在jsp中通过taglib指令引入标签库

  1 <%@ page language="java" contentType="text/html; charset=UTF-8"  2     pageEncoding="UTF-8"%>  3  <!-- uri 为tld中的URI prefix为tld的shortname -->     4  <%@ taglib uri="http://www.baidu.com/jsp/tags" prefix="wsj" %>  5    6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  7 <html>  8 <head>  9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 10 <title>Insert title here</title> 11 </head> 12 <body> 13     您的IP是: 14     <wsj:ShowRemoteIp/> 15 </body> 16 </html>

运行后就是自己IP地址:

2标签的执行过程和原理

JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法。
1、public void setPageContext(PageContext pc), JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
2、public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
3、public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
4、public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。
5、public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。

3标签的扩展功能

  • a、控制标签的主体内容是否显示。

demo1类

  1 package jsptagdemo;  2   3 import java.io.IOException;  4   5 import javax.servlet.jsp.JspException;  6 import javax.servlet.jsp.JspWriter;  7 import javax.servlet.jsp.PageContext;  8 import javax.servlet.jsp.tagext.JspFragment;  9 import javax.servlet.jsp.tagext.SimpleTagSupport; 10  11 public class demo1 extends SimpleTagSupport { 12     private boolean test; //基本类型自动转换  Boolean.parser(String s) 13      14     //标签属性对应这个 15     public void setTest(boolean test) { 16         this.test = test; 17     } 18  19     @Override 20     public void doTag() throws JspException, IOException { 21         //true显示   false默认不处理不显示 22         if(test){ 23             //把主体内容用输出流输出即可 24 //          PageContext pc = (PageContext) getJspContext(); 25 //          JspWriter out = pc.getOut();//得到输出流 26 //          JspFragment jf = getJspBody(); //得到封装了主体内容的jsp片段 27 //          jf.invoke(out); 28              29             getJspBody().invoke(null); //等同于上面代码 看API 30         } 31     } 32 }

tld文件配置

jsp代码

  1 <%@page import="java.util.ArrayList"%>  2 <%@page import="java.util.List"%>  3 <%@ page language="java" contentType="text/html; charset=UTF-8"  4     pageEncoding="UTF-8"%>  5       6 <%@ taglib uri="http://www.baidu.com/jsp/tags" prefix="wsj" %>  7 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  8 <html>  9 <head> 10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 11 <title>控制标签的主体内容是否显示</title> 12 </head> 13 <body> 14     <% 15     List list = new ArrayList(); 16     list.add("haha"); 17     list.add("haha2"); 18     pageContext.setAttribute("list", list); 19     %> 20      21     <wsj:demo1 test="${empty list}"> 22         空 23     </wsj:demo1> 24      25     <wsj:demo1 test="${!empty list}"> 26         不空 27     </wsj:demo1> 28 </body> 29 </html>

运行结果有数据:

  • b、控制结束标签后的内容是否执行。

jsp代码

tld配置

  • c、控制主体内容重复执行(相当于demo1)

jsp代码

  1 <%@ page language="java" contentType="text/html; charset=UTF-8"  2     pageEncoding="UTF-8"%>  3 <%@ taglib uri="http://www.baidu.com/jsp/tags" prefix="wsj" %>  4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  5 <html>  6 <head>  7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  8 <title>Insert title here</title>  9 </head> 10 <body> 11     <wsj:demo3 count="3"> 12         <hr/> 13     </wsj:demo3> 14 </body> 15 </html>

demo3代码

  1 package jsptagdemo;  2   3 import java.io.IOException;  4   5 import javax.servlet.jsp.JspException;  6 import javax.servlet.jsp.tagext.SimpleTagSupport;  7   8 public class demo3 extends SimpleTagSupport {  9     private int count; 10      11     public void setCount(int count) { 12         this.count = count; 13     } 14  15     @Override 16     public void doTag() throws JspException, IOException { 17         for(int i=0; i<count;i++){ 18             getJspBody().invoke(null); 19         } 20     } 21 }
  • d、改变主体内容后输出

java代码

  1 package jsptagdemo;  2   3 import java.io.IOException;  4 import java.io.StringWriter;  5   6 import javax.servlet.jsp.JspContext;  7 import javax.servlet.jsp.JspException;  8 import javax.servlet.jsp.JspWriter;  9 import javax.servlet.jsp.tagext.JspFragment; 10 import javax.servlet.jsp.tagext.SimpleTagSupport; 11 /** 12  * 改变主体内容后输出   大小写转换 13  * @author Angus 14  * 15  */ 16 public class dmeo4 extends SimpleTagSupport { 17     @Override 18     public void doTag() throws JspException, IOException { 19         StringWriter sw  = new StringWriter();//带有缓存的内存输出流 20         //必须先取到主体内容:abcde 21         JspFragment jf = getJspBody(); 22         jf.invoke(sw); 23          24          25         String s = sw.getBuffer().toString();//取到了abcdefg 26          27         JspContext jc = getJspContext(); 28         JspWriter out = jc.getOut(); 29         out.write(s.toUpperCase()); 30          31          32     } 33 }

二、JSTL中的核心标签

Core库中的常用标签:
if choose when otherwise forEach

Core用的少的标签:

  1 <%@page import="com.itheima.domain.Student"%>  2 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  5 <html>  6   <head>  7     <title>Core用的少的标签</title>  8       9     <meta http-equiv="pragma" content="no-cache"> 10     <meta http-equiv="cache-control" content="no-cache"> 11     <meta http-equiv="expires" content="0"> 12     <!-- 13     <link rel="stylesheet" type="text/css" href="styles.css"> 14     --> 15  16   </head> 17    18   <body> 19     <br/>---------c:out输出内容到页面上----------<br/> 20     <c:out value="abc"></c:out> 21     <% 22     pageContext.setAttribute("data1","abcdef"); 23      %> 24      <c:out value="${data1}"></c:out> 25     <% 26     pageContext.setAttribute("data2","<hr/>"); 27      %> 28     <c:out value="${data2}" escapeXml="true"></c:out> 29     <c:out value="${data3}" default="木有"></c:out> 30     <br/>---------c:set存放数据到域对象中;设置JavaBean的属性;设置Map的key和value值----------<br/> 31     <c:set value="pp" var="p"></c:set><!-- pageContext.setAttribute("p","pp") --> 32     ${pageScope.p}<br/> 33     <c:set value="rp" var="p" scope="request"></c:set><!-- request.setAttribute("p","rp") --> 34     ${requestScope.p}<br/> 35     <c:set value="sp" var="p" scope="session"></c:set><!-- session.setAttribute("p","sp") --> 36     ${sessionScope.p}<br/> 37     <c:set value="ap" var="p" scope="application"></c:set><!-- application.setAttribute("p","ap") --> 38     ${applicationScope.p}<br/> 39     <hr/> 40     <% 41     pageContext.setAttribute("s", new Student()); 42      %> 43     ${s.name}<br/> 44     <c:set property="name" target="${s}" value="杨彬彬"></c:set><!-- s.setName("杨彬彬") --> 45     ${s.name} 46     <hr/> 47     <% 48     pageContext.setAttribute("map", new HashMap()); 49      %> 50     <c:set property="k1" value="vvv1" target="${map}"></c:set> 51     ${map.k1} 52     <hr/> 53     <br/>---------c:remove从域范围中删除属性----------<br/> 54      55     <c:remove var="p" scope="request"/> 56     page:${pageScope.p}<br/> 57     request:${requestScope.p}<br/> 58     session:${sessionScope.p}<br/> 59     application:${applicationScope.p}<br/> 60      61     <hr/> 62      63     <c:remove var="p"/><!-- 四个域范围中的所有p删除掉 --> 64     page:${pageScope.p}<br/> 65     request:${requestScope.p}<br/> 66     session:${sessionScope.p}<br/> 67     application:${applicationScope.p}<br/> 68     <br/>---------c:catch抓异常----------<br/> 69     <c:catch var="e"> 70     ${s.sex} 71     </c:catch> 72     ${e.message} 73     <hr/> 74     <br/>---------c:import包含。可以包含任何页面----------<br/> 75     <c:import url="http://www.baidu.com"></c:import> 76   </body> 77 </html>

Core的常用标签:必须掌握

  1 <%@page import="com.itheima.domain.Student"%>  2 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  5 <html>  6   <head>  7     <title>Core的常用标签:必须掌握</title>  8       9     <meta http-equiv="pragma" content="no-cache"> 10     <meta http-equiv="cache-control" content="no-cache"> 11     <meta http-equiv="expires" content="0"> 12     <!-- 13     <link rel="stylesheet" type="text/css" href="styles.css"> 14     --> 15  16   </head> 17    18   <body> 19     <br/>-------c:if模拟java的if语句------------<br/> 20     <c:if test="true"> 21         ok 22     </c:if> 23     <br/>-------c:choose c:when c:otherwise 模拟switch的功能------------<br/> 24     <%pageContext.setAttribute("grade", "D"); %> 25     <c:choose> 26         <c:when test="${grade=='A' }">优秀</c:when> 27         <c:when test="${grade=='B' }">良好</c:when> 28         <c:when test="${grade=='C' }">合格</c:when> 29         <c:otherwise>尚需努力</c:otherwise> 30     </c:choose> 31     <br/>-------c:forEach循环------------<br/> 32     <% 33     List<Student> stus = new ArrayList<Student>(); 34     stus.add(new Student("杨彬彬","male","石家庄",24)); 35     stus.add(new Student("邓冰","female","重庆",25)); 36     stus.add(new Student("陈冠希","male","香港",30)); 37     stus.add(new Student("阿娇","male","石家庄",24)); 38     stus.add(new Student("张柏芝","female","石家庄",24)); 39     pageContext.setAttribute("stus", stus); 40      %> 41      <table border="1"> 42         <tr> 43             <th>序号</th> 44             <th>第一个</th> 45             <th>最后一个</th> 46             <th>姓名</th> 47             <th>性别</th> 48             <th>地址</th> 49             <th>年龄</th> 50         </tr> 51         <!--  52         属性:varStatus:取值为一个字符串,引用一个对象。 53             这个对象他记录了当前元素的一些基本信息。 54             int getIndex():索引号。从0开始 55             int getCount():计数。从1开始 56             boolean isLast():是否是最有一个元素 57             boolean isFirst():是否是第一个元素 58          --> 59         <c:forEach items="${stus}" var="s" varStatus="vs"> 60             <tr bgcolor="${vs.index%2==0?'#c3f3c3':'#f3c3f3'}"> 61                 <td>${vs.count}</td> 62                 <td>${vs.first}</td> 63                 <td>${vs.last}</td> 64                 <td>${s.name}</td> 65                 <td>${s.gender=='male'?'男性':'女性'}</td> 66                 <td>${s.city}</td> 67                 <td>${s.age}</td> 68             </tr> 69         </c:forEach> 70      </table> 71      <hr/> 72      <% 73      pageContext.setAttribute("strs", new String[]{"a","b","c","d","e","f"}); 74       %> 75      <c:forEach items="${strs}" var="s" begin="1" end="5" step="2">${s}</c:forEach> 76      <hr/> 77      <c:forEach begin="1" end="100" var="s">${s}&nbsp;</c:forEach> 78      <br/>-------c:url 自动URL重写 c:param 中文的URL编码------------<br/> 79      <c:url value="/01.jsp" var="u1"> 80         <c:param name="username" value="wzhting"></c:param> 81         <c:param name="password" value="123"></c:param> 82         <c:param name="city" value="济南"></c:param> 83      </c:url> 84      <a href="${u1}">猛戳这里</a> 85   </body> 86 </html>

三、国际化(了解)

软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
国际化又称为 i18n:internationalization

1、固定文本的国际化

把文本写在不同的properties文件中。
一个消息资源包由多个properties文件组成的,但这些文件有着以下的约定:

  • 基本文件名一致:msg_zh_CN.properties msg_en_US.properties (ISO)
  • 文件中有着相同的key,但是value不同

测试

  1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2   3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5     <%  6     //得到来访者的语言信息  7     Locale locale = request.getLocale();//Accpet-Language  8     ResourceBundle rb = ResourceBundle.getBundle("com.itheima.resources.msg",locale);  9     %> 10   <head> 11     <title><%=rb.getString("jsp.login.title") %></title> 12      13     <meta http-equiv="pragma" content="no-cache"> 14     <meta http-equiv="cache-control" content="no-cache"> 15     <meta http-equiv="expires" content="0"> 16     <!-- 17     <link rel="stylesheet" type="text/css" href="styles.css"> 18     --> 19  20   </head> 21    22   <body> 23     <form action=""> 24         <%=rb.getString("jsp.login.username") %>:<input/><br/> 25         <%=rb.getString("jsp.login.password") %>:<input/><br/> 26         <input type="submit" value="<%=rb.getString("jsp.login.submit") %>"/> 27     </form> 28   </body> 29 </html>

单元测试

  1 package com.itheima;  2   3 import java.util.Locale;  4 import java.util.ResourceBundle;  5   6 import org.junit.Test;  7   8 public class I18nTextDemo {  9     //按照本地(中国)的默认区域信息获取内容 10     @Test 11     public void test1(){ 12         ResourceBundle rb = ResourceBundle.getBundle("resources.msg"); 13         System.out.println(rb.getString("hello")); 14     } 15     //按照指定的区域信息获取内容 16     @Test 17     public void test2(){ 18         ResourceBundle rb = ResourceBundle.getBundle("resources.msg",Locale.US); 19         System.out.println(rb.getString("hello")); 20     } 21 }

2、日期时间的格式化

  • 存数据:form—->JavaBean。用户输入的都是String类型—–>JavaBean:其他类型.parser(String)
  • 显示数据:JavaBean—–>JSP页面上。显示的都是String类型.其他类型——>String类型.String format(Object)

  1 package com.wsj;  2   3 import java.text.DateFormat;  4 import java.text.ParseException;  5 import java.util.Date;  6 import java.util.Locale;  7   8 import org.junit.Test;  9  10 public class DateFormatDemo { 11     //FULL: Monday, November 17, 2014 4:47:28 PM CST 12  13     /*内置的样式。自由指定样式请使用SimpleDateFormat:yyyy-MM-dd 14     FULL: 2014年11月17日 星期一                             下午04时44分12秒 CST 15     LONG: 2014年11月17日                                          下午04时45分44秒 16     MEDIUM:2014-11-17               16:46:12 17     DEFAULT:2014-11-17               16:46:12 18     SHORT: 14-11-17                                               下午4:46 19      */ 20      21     @Test 22     public void test1(){ 23         DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US); 24         Date now = new Date(); 25         String s = df.format(now); 26         System.out.println(s); 27     } 28     @Test 29     public void test2() throws ParseException{ 30         DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US); 31         String s = "Monday, November 17, 2014 4:47:28 PM CST"; 32         Date d = df.parse(s);//不符合格式 33         System.out.println(d); 34     } 35 }

3、货币的格式化

  1 package com.wsj;  2   3 import java.text.NumberFormat;  4 import java.text.ParseException;  5 import java.util.Locale;  6   7 import org.junit.Test;  8   9 public class NumberFormatDemo { 10     @Test 11     public void test1() throws ParseException{ 12         int money = 10000000; 13         NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US); 14         String s = nf.format(money); 15         System.out.println(s); 16          17         String s1 = "$10,000,000.00"; 18         Number n = nf.parse(s1); 19         System.out.println(n); 20     } 21 }

4批量国际化

  1 package com.wsj;  2   3 import java.text.DateFormat;  4 import java.text.MessageFormat;  5 import java.text.NumberFormat;  6 import java.util.Calendar;  7 import java.util.Date;  8 import java.util.Locale;  9  10 import org.junit.Test; 11  12 public class MessageFormatDemo { 13     //批量国际化:出现很多区域敏感信息 14     @Test 15     public void test2(){ 16         Locale l = Locale.US; 17         //发生的时间//发生的日期 18         Calendar c = Calendar.getInstance(); 19         c.set(1998, 6, 3, 12, 30, 00); 20         Date d = c.getTime(); 21          22         int money = 1000000; 23          24         String pattern = "At {0,time,medium} on {1,date,long }, a hurricance destroyed 99 houses and caused {2,number,currency} of damage"; 25         MessageFormat mf = new MessageFormat(pattern, l); 26         String s = mf.format(new Object[]{d,d,money}); 27         System.out.println(s); 28     } 29     //批量国际化:出现很多区域敏感信息 30     @Test 31     public void test1(){ 32         Locale l = Locale.US; 33         //发生的时间//发生的日期 34         Calendar c = Calendar.getInstance(); 35         c.set(1998, 6, 3, 12, 30, 00); 36         Date d = c.getTime(); 37          38         int money = 1000000; 39          40          41         DateFormat df1 = DateFormat.getTimeInstance(DateFormat.DEFAULT,l); 42         String time = df1.format(d);//12:30 pm    43          44         DateFormat df2 = DateFormat.getDateInstance(DateFormat.LONG , l); 45         String date = df2.format(d);//jul 3,1998 46          47         NumberFormat nf = NumberFormat.getCurrencyInstance(l); 48         String smoney = nf.format(money); 49          50          51         String s = "At "+time+" on "+date+", a hurricance destroyed 99 houses and caused "+smoney+" of damage"; 52         System.out.println(s); 53     } 54 }

JSTL中的国际化标签

引入:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5     <fmt:setLocale value="${pageContext.request.locale}"/>  6     <fmt:setBundle basename="com.itheima.resources.msg" var="msg"/>  7   <head>  8     <title>  9         <fmt:message bundle="${msg}" key="jsp.login.title"/> 10     </title> 11      12     <meta http-equiv="pragma" content="no-cache"> 13     <meta http-equiv="cache-control" content="no-cache"> 14     <meta http-equiv="expires" content="0"> 15     <!-- 16     <link rel="stylesheet" type="text/css" href="styles.css"> 17     --> 18  19   </head> 20    21   <body> 22     <form action=""> 23         <fmt:message bundle="${msg}" key="jsp.login.username"/>:<input/><br/> 24         <fmt:message bundle="${msg}" key="jsp.login.password"/>:<input/><br/> 25         <input type="submit" value="<fmt:message bundle="${msg}" key="jsp.login.submit"/>"/> 26     </form> 27     日期:<hr/> 28     <% 29     pageContext.setAttribute("now", new Date()); 30      %> 31      date1:${now}<br/> 32      <fmt:formatDate value="${now}"/><br/> 33      <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="short"/><br/> 34      <fmt:formatDate value="${now}" type="time"/><br/> 35      <fmt:formatDate value="${now}" pattern="yyyy年MM月dd日"/><br/> 36   </body> 37 </html>