JSTL标签国际化操作及怎样书写自己的JSTL标签
JSTL标签
1、 JSTL
a) 四个标签、一个函数。
1、 Core核心标签 – 必须的。
2、 Fmt标签 – 国际化,i18n –
3、 [微软用户1] Sql – 不用
4、 Xml – 在页面上操作xml
5、 Fn – function 用于处理字符串或是处理list。 [微软用户2]
1.1、i18n国际化
在JDK中一个类
ResourceBoundle – 专门用于绑定国际化的资源文件 、
对于中文的资源文件,必须要经过编码。
C:/> native2ascii 你好
\u3243\uasd
A、示例
创建两个资源文件
对中文的信息进行编码:
C:/> native2ascii a.txt b.txt
public class I18NDemo {
@Test
public void test1(){
//声明资源的绑定类
//先会根据本地信息,读取相关的配置文件,如果没有则读取默认的配置文件
//可以指定读取哪一个文件
ResourceBundle rb =
ResourceBundle.getBundle("a",Locale.US);
//获取值
String name = rb.getString("name");
String addr = rb.getString("addr");
System.err.println(name+","+addr);
}
}
以下是Local类:
@Test
public void test2(){
Locale lo = Locale.getDefault();//获取本地的语言,国家
System.err.println(lo.getDisplayCountry());
System.err.println(lo.getDisplayLanguage());
}
}
1.2、页面如何实现国标化
<fmt:标签实现国际化.
Fmt:setBoundle – 设置绑定哪一个资源文件。
Fmt:getMessage 获取信息.
Fmt:setLocal
A:基本的使用方式
<!-- 设置读取哪一个资源文件 -->
<fmt:setBundle basename="a"/>
</head>
<body>
主页...
<hr/>
<fmt:message key="name"></fmt:message>
<br/>
<fmt:message key="addr"></fmt:message>
</body>
</html>
B:实现让用户选择
<fmt:setLocal/>
<!-- 在读取文件之前,设置语言 -->
<fmt:setLocale value="${param.language}"/>
<!-- 设置读取哪一个资源文件 -->
<fmt:setBundle basename="a"/>
</head>
<body>
<div style="text-align:right;">
<a href="?language=en_US">English</a>
|
<a href="?language=zh_CN">中文</a>
</div>
<hr/>
<fmt:message key="name"></fmt:message>
<br/>
<fmt:message key="addr"></fmt:message>
</body>
</html>
<!-- 在读取文件之前,设置语言 -->
<fmt:setLocale value="${param.language}" scope="session"/[微软用户3] >
接收参数的:
name=Jack
addr=JiNan ShangDong
welcome=welcome you and your name is {0},your addr is {1}
最大值为{0}~{9}
<!-- 设置读取哪一个资源文件 -->
<fmt:setBundle basename="a"/>
</head>
<body>
<!-- 通过国际化标签设置编码 -->
<fmt:requestEncoding value="UTF-8"/>[微软用户4]
<hr/>
<fmt:message key="name"></fmt:message>
<br/>
<fmt:message key="addr"></fmt:message>
<hr/>
<fmt:message key="welcome">
<fmt:param value="${param.name}"></fmt:param>
<fmt:param value="${param.addr}"></fmt:param>
</fmt:message>
[微软用户5] </body>
</html>
处理数字类型:
<br/>对sum进行取整
<fmt:formatNumber value="${sum}"
pattern="#.00"></fmt:formatNumber>
<br/>
<fmt:formatNumber
value="12345.45678" pattern="#,###.00"></fmt:formatNumber>
-----------图片的处理-----
name=\u6770\u514b
addr=\u5c71\u4e1c\u7701\u6d4e\u5357\u5e02
welcome=\u4f60\u597d\uff0c\u6b22\u8fce\u4f60\uff0c\u4f60\u53eb {0},\u4f60\u7684\u5730\u5740\u662f {1}
img1=a.jpg
1.3、fn函数操作
使用方式语法:
${fn:substring(...)}
</pre>
bbbbbbb.jsp<br/>
${fn:contains(nm,'b')}<br/>
<!-- 接收参数 -->
<c:set var="mail" value="${param.mail}"></c:set>
<c:set var="atIndex" value="${fn:indexOf(mail,'@')}"></c:set>
<c:set var="dotIndex" value="${fn:indexOf(mail,'.')}"></c:set>
<hr/>
以下是你的邮件:
${fn:substring(mail,atIndex+1,dotIndex)}
<br/>
2、自定义标签
标签的是如何开发出来的?
验证用户是否重复提交表单。
生成表单。
实现用户的安全验证.
2.1、Tag接口是标签的最高接口
标签组成
开一个自定义的标签:
1:实现tag接口。
2:给这个标签添加一个配置文件,应该放到WEB-INF/*.tld
3:在页面上引用这个标签
第一步:实现Tag接口
package cn.oracle.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
/**
* 自己的第一个标签
* 必须要拥有一个无参数的公开构造
*/
public class HelloTag implements Tag{
public void setPageContext(PageContext pc) {
System.err.println("1:设置了pc对象:"+pc);
}
//只能返回两个值
//EVAL_BODY_INCLUDE - 包含body体的部分
//SKIP_BODY - 跳过body部分
public int doStartTag() throws JspException {
System.err.println("2:标签开始了:");
return Tag.EVAL_BODY_INCLUDE;
}
//只能返回
//SKIP_PAGE - 跳过page后面的部分不显示
//EVAL_PAGE - 执行页面的后面的部分
public int doEndTag() throws JspException {
System.err.println("3:标签结束了");
return EVAL_PAGE;
}
public void release() {
}
public void setParent(Tag t) {
}
public Tag getParent() {
return null;
}
}
第二步:在web-inf/tag/hello.tld文件
<description>这是我第一个标签</description>
<display-name>Hello</display-name>
<tlib-version>1.0</tlib-version>
<short-name>hello</short-name>
<!-- 用于在页面上设置引用的 -->
<uri>http://www.jtedu.com</uri>
<!--
<uri>/www.jtedu.com</uri>
<uri>/aaa.tld</uri>
-->
<!-- 以下开始声明标签 -->
<tag>
<!-- 设置标签的子名称<hello:world -->
<name>world</name>
<!-- 设置哪一个类是标签类 -->
<tag-class>cn.oracle.tag.HelloTag</tag-class>
<!-- 声明body部分的数据是什么 -->
<body-content>JSP</body-content>
</tag>
</taglib>
第三步:在页面上引用
<%@ taglib uri="http://www.jtedu.com" prefix="hello"%>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%=pageContext %>
<br/>
<hello:world>这是body部分</hello:world>
这是标签后面的部分。。
</body>\
第五步:修改标签,在页面上输出hello
要想在页面上输出信息,必须要在doStartTag,或是doEndTag中输出到页面:
public class HelloTag implements Tag{
private PageContext pc;
public void setPageContext(PageContext pc) {
System.err.println("1:设置了pc对象:"+pc);
this.pc=pc;[微软用户6]
}
//只能返回两个值
//EVAL_BODY_INCLUDE - 包含body体的部分
//SKIP_BODY - 跳过body部分
public int doStartTag() throws JspException {
System.err.println("2:标签开始了:");
//获取输出对象
JspWriter out = pc.getOut();[微软用户7]
try {
out.print("<br/>你好,这是标签的开始。。。");
} catch (IOException e) {
throw new RuntimeException(e);
}
return SKIP_BODY;
}
//只能返回
//SKIP_PAGE - 跳过page后面的部分不显示
//EVAL_PAGE - 执行页面的后面的部分
public int doEndTag() throws JspException {
System.err.println("3:标签结束了");
JspWriter out = pc.getOut();
try {
out.print("<br/>你好,这是标签的结束。。。");
} catch (IOException e) {
throw new RuntimeException(e);
}
return EVAL_PAGE;
}
public void release() {
}
public void setParent(Tag t) {
}
public Tag getParent() {
return null;
}
}
标签的配置说明:
功能1:
要求在页面上输入服务器时间.
方案:
1:可以在页面上使用<%=new Date()%>。
2:可以使用标签。
标签类的实现关系:
第一步:开发一个类,继承TagSupport这个标签支持类
package cn.oracle.tag;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class DateTag extends TagSupport {
private static final long serialVersionUID = 1L;
//只实现部分方法
@Override
public int doStartTag() throws JspException {[微软用户8]
//获取时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String ctime = sdf.format(new Date());
//获取输出对象JspWriter
JspWriter out = pageContext.getOut();[微软用户9]
//输出时间
try{
out.print(ctime);
}catch(Exception e){
throw new RuntimeException(e);
}
return super.doStartTag();
}
}
第二步:将这个类,配置到tld文件中
<!-- 配置第二个标签类 -->
<tag>
<name>date</name>
<tag-class>cn.oracle.tag.DateTag</tag-class>
<body-content>empty</body-content>
</tag>
第三步:在页面上引用
<hr/>
时间:<hello:date/>
2.3、带属性的标签
<hello:date name="张三"/> - > 我好张三,时间为:2009年
做两步:
1:在标签类上,添加setXxx方法。
2:在tld文件中声明这是一个有属性的标签。
第一步:在HelloTag.java中声明以下
private String myName;
//声明一个设置的方法
public void setName(String nm){
this.myName=nm;
}
第二步:修改doStartTag方法
String str = "你好:"+myName+",时间为:"+ctime;
out.print(str);
第三步:修改tld文件
<!-- 配置第二个标签类 -->
<tag>
<name>date</name>
<tag-class>cn.oracle.tag.DateTag</tag-class>
<body-content>empty</body-content>
<!-- 以下声明这个类的属性 -->
<attribute>
<!-- 属性的名称,必须要与setName匹配 -->
<name>name</name>
<!-- 声明这个属性是否是必须设置的 -->
<required>true</required>
<!--
runtime exp : 是否支持运行时的表达式的值.
name="Jack" - 直接写死的
name="${param.name}"
-->
<rtexprvalue>true</rtexprvalue>
<!-- 数据类型 -->
<type>java.lang.String</type>
</attribute>
</tag>
2.4、实现c:url的功能
<p>要求自己实现c:url的功能</p>
<pre>
<c:url vlaue = "/"> = > /0428
1:获取项目的根 - request.getContextPath();
2:重写url ;jsessionid=99999 - response.encodURL("a.jsp")
</pre>
第一步:开发一个类继承tagSupport
package cn.oracle.tag;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class UrlTag extends TagSupport {
//声明一个属性用户接收用户的设置
private String path;
public void setPath(String path) {
this.path = path;
}
@Override
public int doStartTag() throws JspException {
//1:获取项目的根
HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
String contextPath =req.getContextPath();
//将用户的地址加到后面
contextPath+=path;
//2:重写url
HttpServletResponse resp =
(HttpServletResponse) pageContext.getResponse();
String url = resp.encodeURL(contextPath);
//3:写出
JspWriter out = pageContext.getOut();
try{
out.print(url);
}catch(Exception e){
throw new RuntimeException(e);
}
//返回一个不处理body部分
return Tag.SKIP_BODY;
}
}
第二步:配置到tld.中去
<display-name>url</display-name>
<tlib-version>1.0</tlib-version>
<short-name>u</short-name>
<uri>http://www.jtedu.com/url</uri>
<!-- 声明这标签 -->
<tag>
<name>url</name>
<tag-class>cn.oracle.tag.UrlTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>path</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
</taglib>
第三步:在页面上与c:url对比
<hr/>
<u:url path="/jsp/a.jsp"/>
<hr/>
<c:url value="/jsp/a.jsp"/>
2.5、防止重复提交
重复提交:用户在提交了表单以后执行的刷新操作,其实是重新向服务器请求的过程,所以会造成重复提交。
演示效果:
第一步:RegServlet
public class RegServlet extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//1:设置编码
request.setCharacterEncoding("UTF-8");
//2:接收用户的信息
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
if(name!=null && !name.trim().equals("")){
//生成一个随机的id
String uuid = UUID.randomUUID().toString().replace("-","");
//调用dao层保存用户
System.err.println("调用dao保存了用户的信息:"+uuid+","+name+","+pwd);
//为了给用户显示一下生成的id
//将生成的id放到request域中
request.setAttribute("id",uuid);
//只要是request域中有数据则必须要使用转发
request.getRequestDispatcher("/regsucc.jsp").forward(request, response);
}else{
//设置一个错误信息到session中去
request.getSession().setAttribute("error","你的注册信息错误");
//重定向到注册面
response.sendRedirect(request.getContextPath()+"/reg.jsp");
}
}
}
第二步:
<body>
<p>注册</p>
<form action="<c:url value='/RegServlet'/>" method="post">
Name:<input type="text" name="name"><br/>
pwd:<input type="text" name="pwd"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
第三步:开发显示成功的页面
<body>
<p>你好,注册成功了</p>
你的生成的id:${requestScope.id}
</body>
第四步:为了防止重复提交
1:可以在表单中保存一个随机值。-用户会在提交时会带这个值到RegServlet中来.
2:同时将这个值放到session中,则在regServlet中也可以取出来。
3:就进行比较,如果一样,就可以提交。保存到数据库。否则就提示不能重复提交。
<%
//生成一个uuid的值
String uid = UUID.randomUUID().toString().replace("-","");
//再将这个uid放到session
session.setAttribute("aa", uid)[微软用户10] ;
%>
<p>注册</p>
<form action="<c:url value='/RegServlet'/>" method="post">
Name:<input type="text" name="name"><br/>
pwd:<input type="text" name="pwd"><br/>
<input type="hidden" value="<%=uid%>[微软用户11] " name="uuud">
<input type="submit" value="提交">
</form>
第五步:在servlt中处理两个值的对比
public class RegServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 1:设置编码
request.setCharacterEncoding("UTF-8");
// 2:接收用户的信息
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String xd = request.getParameter("uuud");// 获取用户提交的值
// 同时从session中取出值
String xd2 = (String) request.getSession().getAttribute("aa");
[微软用户12] if (xd.equals(xd2)) {
if (name != null && !name.trim().equals("")) {
// 生成一个随机的id
String uuid = UUID.randomUUID().toString().replace("-", "");
// 调用dao层保存用户
System.err.println("调用dao保存了用户的信息:" + uuid + "," + name + ","
+ pwd);
//在保存成功以后,就将对比码删除
request.getSession().removeAttribute("aa");[微软用户13]
// 为了给用户显示一下生成的id
// 将生成的id放到request域中
request.setAttribute("id", uuid);
// 只要是request域中有数据则必须要使用转发
request.getRequestDispatcher("/regsucc.jsp").forward(request,
response);
} else {
// 设置一个错误信息到session中去
request.getSession().setAttribute("error", "你的注册信息错误");
// 重定向到注册面
response.sendRedirect(request.getContextPath() + "/reg.jsp");
}
}else{
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("你不能重复提交");
}
}
}
第六步:问题
1:在JSP上出现Java代码。
解决方法:
用标签实现。
开发一个标签类:
package cn.oracle.tag;
import java.util.UUID;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class ValidateTag extends TagSupport{
public int doEndTag() throws JspException {
//1:生成UUID放到session
String uuid = UUID.randomUUID().toString().replace("-","");
pageContext.getSession().setAttribute("aa", uuid);
//2:输出页面上去
String html = "<input type='text' name='uuud' value='"+uuid+"'>";
//3:输出这个html到页面上
JspWriter out = pageContext.getOut();
try{
out.print(html);
}catch(Exception e){
throw new RuntimeException(e);
}
return EVAL_PAGE;
}
}
配置这个标签类:
<display-name>v</display-name>
<tlib-version>1.0</tlib-version>
<short-name>v</short-name>
<uri>/validate.tld</uri>
<!-- 定义标签 -->
<tag>
<name>hidden</name>
<tag-class>cn.oracle.tag.ValidateTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
在页面上引用这个标签:
<%@ taglib uri="/validate.tld" prefix="v" %>[微软用户14]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<p>注册</p>
<form action="<c:url value='/RegServlet'/>" method="post">
Name:<input type="text" name="name"><br/>
pwd:<input type="text" name="pwd"><br/>
<v:hidden/>[微软用户15]
<input type="submit" value="提交">
</form>
</body>
</html>
测试。
第七步:问题
<form action="<c:url value='/RegServlet'/>" method="post">
Name:<input type="text" name="name"><br/>
pwd:<input type="text" name="pwd"><br/>
VVVV:<v:hidden/><br/>
<input type="submit" value="提交">
</form>
对于 <v:hidden/>来说,生成什么什么样的html开发人员不知道。
向session中放什么key,程序员也不知道。
以上图示,说明应该给ValidateTag添加一个name属性:
且要求用户必须要提供这个属性的值:
1:o在类中声明一个setName。
2:在*.tld文件中添加attibute元素配置。
public class ValidateTag extends TagSupport{
//接收用户的设置的参数
private String elementName;
public void setName(String name){[微软用户16]
this.elementName=name;
}
public int doEndTag() throws JspException {
//1:生成UUID放到session
String uuid = UUID.randomUUID().toString().replace("-","");
pageContext.getSession().setAttribute(this.elementName[微软用户17] , uuid);
//2:输出页面上去
String html = "<input type='text' name='"+elementName[微软用户18] +"' value='"+uuid+"'>";
//3:输出这个html到页面上
JspWriter out = pageContext.getOut();
try{
out.print(html);
}catch(Exception e){
throw new RuntimeException(e);
}
return EVAL_PAGE;
}
}
修改tld文件
<tag>
<name>hidden</name>
<tag-class>cn.oracle.tag.ValidateTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
修改JSP页面
<form action="<c:url value='/RegServlet'/>" method="post">
Name:<input type="text" name="name"><br/>
pwd:<input type="text" name="pwd"><br/>
VVVV:<v:hidden name="vid[微软用户19] "/><br/>
<input type="submit" value="提交">
</form>
修改regServlet中的获取值的参数
request.setCharacterEncoding("UTF-8");
// 2:接收用户的信息
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String xd = request.getParameter("vid");// 获取[微软用户20] 用户提交的值
// 同时从session中取出值
String xd2 = (String) request.getSession().getAttribute("vid"[微软用户21] );
请回答:
防止重复提交的关键点是什么:
判断用户提交的,与session中保存的,是否一样。
2.6、实现遍历的标签
Tag
IteratorTag
TagSupport可以实现遍历.
以下实现一个输出1..10的遍历的结果
以下是最基本的输出1...10
public class EachTag extends TagSupport{
private int i=0;
public EachTag() {
System.err.println("构造方法");
}
@Override
public int doStartTag() throws JspException {
//在执行body之前.放一个值到pageContext中去
pageContext.setAttribute("nn",++i);
//返回包含body部分,以说明可以执行body部分,只有执行了body部分才会
//执行到body部分的结束,
//只有执行到body部分的结束才会调用doAfterBody方法
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
if(i<10){
//如果小于10就执行body部分再来次
pageContext.setAttribute("nn",++i);
return EVAL_BODY_AGAIN;
}else{
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
//设置回原来的值
i=0;
return EVAL_PAGE;
}
}
以下可以让用户来配置变量名
<for:each var="nn">
${nn}<br/>
</for:each>
1:就是set方法
以下实现任意的从某个数字到终点:
主页<br/>
<for:each start="${param.s}" end="${param.e}" var="mm1">
${mm1}<br/>
</for:each>
代码:
public class EachTag extends TagSupport{
//声明成员变量
private String var;
private Integer start=0;
private Integer end = 0;
public void setStart(Integer start) {
this.start = start;
}
public void setEnd(Integer end) {
this.end = end;
}
//设置值
public void setVar(String var) {
this.var = var;
}
public EachTag() {
System.err.println("构造方法");
}
@Override
public int doStartTag() throws JspException {
//在执行body之前.放一个值到pageContext中去
pageContext.setAttribute(var,start++);
//返回包含body部分,以说明可以执行body部分,只有执行了body部分才会
//执行到body部分的结束,
//只有执行到body部分的结束才会调用doAfterBody方法
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
if(start<=end){
//如果小于10就执行body部分再来次
pageContext.setAttribute(var,start++);
return EVAL_BODY_AGAIN;
}else{
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
//设置回原来的值
start=0;
return EVAL_PAGE;
}
}
配置文件:
<tag>
<name>each</name>
<tag-class>cn.oracle.tag.EachTag</tag-class>
<body-content>JSP</body-content>
<!-- 添加属性 -->
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>start</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.Integer</type>
</attribute>
<attribute>
<name>end</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.Integer</type>
</attribute>
</tag>
2.7、遍历集合,数组
以下实现的一个遍历List的测试
Object o = 2;//Integer,int
Object o2 = new String(“ddd”);
2、 MVC_开发模式
a) 示例
3、 增强HttpServlet之BaseServlet
4、 在MVC模式中如何管理数据库的事务。
a) ThreadLocal模式。
b) 动态代理所有Service层。
5、分页