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

自定义标签,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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值