Struts1.X学习笔记 8月28日
2009
[在此处键入文档的摘要。摘要通常是对文档内容的简短总结。在此处键入文档的摘要。摘要通常是对文档内容的简短总结。] MVC框架以及标签的使用
Structs1.x框架工作流程
方法介绍
Action是Struct父接口,其中里面的方法是public ActionForward
execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){}
throws Exception
ActionForm是获取表单中的数据
ActiionForward是进行转向处理
工作流程
response
dispatch
response
request
JSP
Struts Taglib(标签)
Struts 标签的配置和使用
配置:
* 在struts-config.xml文件中加入
<message-resources parameter="MessageResources" />
* 拷贝MessageResources.properties文件到src下
使用:
* 采用taglib指令引入
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%>
<%@ taglib prefix="logic" uri="http://struts.apache.org/tags-logic"%>
Struts 常使用的标签如下:
<bean:write name=””>等同于request.getAttribute(“”)/或是request.getPrameatery(“”)
<logic:empty> </logic:empty>
<logic:notEmpty name="attr3"></logic:notEmpty>
<logic:present></logic:present>
<logic:notPresent></logic:notPresent>是逻辑判断标记相当于if else
JSTL标签的使用(学习的重点,必须掌握)
简介:SUN的标准taglib库
Jsp标准标签库(jsp standard Tag Library,JSTL)
迭代和条件判断
数据管理格式化
XML操作
数据库访问
函数标签库
表达式语言(EL)
El隐式对象
存取器
运算符
EL实例如下:
<h1>测试EL表达式</h1><br>
<hr>
<li>普通字符串</li><br>
hello(jsp脚本):<%=request.getAttribute("hello") %><br>
hello(el表达式,el表达式的使用方法$和{}):${hello }<br>
hello(el表达式,el的隐含对象pageScope,requestScope,sessionScope,applicationScope,<br> 如果未指定scope,它的搜索顺序为pageScope~applicationScope):${requestScope.hello }<br>
hello(el表达式,scope=session):${sessionScope.hello }<br>
<p>
<li>结构,采用.进行导航,也称存取器</li><br>
姓名:${user.username }<br>
年龄:${user.age }<br>
所属组:${user.group.name }<br>
<p>
<li>输出map,采用.进行导航,也称存取器</li><br>
mapvalue.key1:${mapvalue.key1 }<br>
mapvalue.key2:${mapvalue.key2 }<br>
<p>
<li>输出数组,采用[]和下标</li><br>
strarray[2]:${strarray[1] }<br>
<p>
<li>输出对象数组,采用[]和下标</li><br>
userarray[3].username:${users[2].username }<br>
<p>
<li>输出list,采用[]和下标</li><br>
userlist[5].username:${userlist[4].username }<br>
<p>
<li>el表达式对运算符的支持</li><br>
1+2=${1+2 }<br>
10/5=${10/5 }<br>
10 div 5=${10 div 5 }<br>
10%3=${10 % 3 }<br>
10 mod 3=${10 mod 3 }<br>
<!--
==/eq
!=/ne
</lt
>/gt
<=/le
>=/ge
&&/and
||/or
!/not
//div
%/mod
-->
<li>测试empty</li><br>
value1:${empty value1 }<br>
value2:${empty value2 }<br>
value3:${empty value3 }<br>
value4:${empty value4 }<br>
value4:${!empty value4 }<br>
JSTL_核心库标签
<h1>测试jstl核心库</h1>
<hr>
<li>测试c:out</li><br>
hello(default):<c:out value="${hello}"/><br>
hello(el表达式):${hello }<br>
hello(default="123"):<c:out value="${abc}" default="123"/><br>
hello(default="123"):<c:out value="${abc}">123</c:out><br>
bj(defalut):<c:out value="${bj}"/><br>
bj(escapeXml="true"):<c:out value="${bj}" escapeXml="true"/><br>
bj(escapeXml="false"):<c:out value="${bj}" escapeXml="false"/><br>
bj(el表达式):${bj }<br>
<p>
<li>测试c:set和c:remove</li><br>
<c:set value="123" var="temp"/>
temp:${temp }<br>
<c:remove var="temp"/>
temp:${temp }<br>
<p>
<li>测试条件控制标签c:if</li><br>
<c:if test="${v1 lt v2}" var="v">
v1小于v2<br>v=${v }<br>
</c:if>
<c:if test="${empty v3}">
v3为空<br>
</c:if>
<c:if test="${empty v4}">
v4为空<br>
</c:if>
<p>
<li>测试条件控制标签c:choose,c:when,c:otherwise</li><br>
<c:choose>
<c:when test="${v1 lt v2}">
v1小于v2<br>
</c:when>
<c:otherwise>
v1大于v2<br>
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${empty v4}">
v4为空<br>
</c:when>
<c:otherwise>
v4不为空<br>
</c:otherwise>
</c:choose>
<p>
<li>测试循环控制标签c:forEach</li><br>
<table border="1">
<tr>
<td>姓名</td>
<td>年龄</td>
<td>所属组</td>
</tr>
<c:choose>
<c:when test="${empty userlist}">
<tr>
<td colspan="3">没有符合条件的数据!</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${userlist}" var="u">
<tr>
<td>${u.username }</td>
<td>${u.age }</td>
<td>${u.group.name }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
<p>
<li>测试循环控制标签c:forEach,varstatus</li><br>
<table border="1">
<tr>
<td>姓名</td>
<td>年龄</td>
<td>所属组</td>
</tr>
<c:choose>
<c:when test="${empty userlist}">
<tr>
<td colspan="3">没有符合条件的数据!</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${userlist}" var="user" varStatus="vs">
<c:choose>
<c:when test="${vs.count % 2 == 0}">
<tr bgcolor="red">
</c:when>
<c:otherwise>
<tr>
</c:otherwise>
</c:choose>
<td>
<c:out value="${user.username}"/>
</td>
<td>
<c:out value="${user.age}"/>
</td>
<td>
<c:out value="${user.group.name}"/>
</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
<p>
<li>测试循环控制标签c:forEach,begin,end,step</li><br>
<table border="1">
<tr>
<td>姓名</td>
<td>年龄</td>
<td>所属组</td>
</tr>
<c:choose>
<c:when test="${empty userlist}">
<tr>
<td colspan="3">没有符合条件的数据!</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${userlist}" var="user" begin="2" end="8" step="2">
<tr>
<td>${user.username}</td>
<td>${user.age}</td>
<td>${user.group.name }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
<p>
<li>测试循环控制标签c:forEach,普通循环</li><br>
<c:forEach begin="1" end="10">
a<br>
</c:forEach>
<p>
<li>测试循环控制标签c:forEach,输出map</li><br>
<c:forEach items="${mapvalue}" var="v">
${v.key }=${v.value }<br>
</c:forEach>
<p>
<li>测试循环控制标签c:forTokens</li><br>
<c:forTokens items="${strTokens}" delims="," var="v">
${v }<br>
</c:forTokens>
<p>
<li>测试c:catch</li><br>
<%
try {
Integer.parseInt("asdfsdf");
}catch(Exception e) {
out.println(e.getMessage());
}
%>
<p>
<c:catch var="exinfo">
<%
Integer.parseInt("asdfsdf");
%>
</c:catch>
${exinfo }<br>
<p>
<li>测试c:import</li><br>
<c:import url="http://localhost:8080/struts_login"/>
<p>
<li>测试c:url和c:param</li><br>
<c:url value="http://localhost:8080/drp/sysmgr/user_add.jsp" var="v">
<c:param name="username" value="Jack"/>
<c:param name="age" value="20"/>
</c:url>
${v }<br>
<li>测试:redirect</li><br>
<c:redirect context="/struts_login" url="/index.jsp"/>
Jstl格式化标签的使用
实例
<li>fmt时间格式化</li><br>
date(default):<fmt:formatDate value="${date}" var="d" /><br>
d=${d}<br>
date(type="time"):<fmt:formatDate value="${date}" type="time"/><br>
date(type="date"):<fmt:formatDate value="${date}" type="date"/><br>
date(type="both" ):<fmt:formatDate value="${date}" type="both"/><br>
date(type="both" dateStyle="long"):<fmt:formatDate value="${date}" type="both" dateStyle="long"/><br>
date(type="both" dateStyle="full"):<fmt:formatDate value="${date}" type="both" dateStyle="full" /><br>
date(type="both" timeStyle="full"):<fmt:formatDate value="${date}" type="both" timeStyle="full" dateStyle="full" /><br>
date(type="both" pattern="yyyy-mm-dd hh-mm=ss" ):<fmt:formatDate value="${date}" pattern="yyyy-mm-dd hh-mm-ss" />
<li>数字的 格式化</li><br>
数字的格式化(default):<fmt:formatNumber value="${number}"></fmt:formatNumber><br>
数字格式化(type="number"):<fmt:formatNumber value="${number}" pattern="###,###.0000" type="number" maxIntegerDigits="10" maxFractionDigits="2" ></fmt:formatNumber>
<br>数字格式化 (type="currency"):<fmt:formatNumber value="${number}" type="currency" var="m"></fmt:formatNumber><br>
总共的金额是:${m}<br>
百分比(pdate type="percent" ): <fmt:formatDate value="${pdate}" type="percent" var="p" pattern=".0000" />
${p}<br>
JSTL函数库(以及自定义函数库)
自定义函数的规则
jstl_fn自定义函数库:
1、定义类和方法(方法必须是public static)
2、编写自定义tld文件,并且将此文件放到WEB-INF或WEB-INF任意子目录下
3、在jsp中采用taglib指令引入自定义函数库
4、采用 前缀+冒号+函数名 调用即可
实例
<h4 align="center">jstl函数库的测试</h4>
<li>和那书库的测试</li><br>
hello(jsp 脚本):<%=((String)request.getAttribute("hello")).length() %> <br>
helo(jstl函数库,函数调用必须在el表达式中 前缀+冒号+函数名):${fn:length(hello)}<br>
list集合的长度:${fn:length(list) }
<li>自定义和那书库的测试</li><br>
sayHello(自定义函数):${myfunction:sayhello(name)}
动态ActionForm(可以动态的获取页面提交的数据)
1、动态ActionForm
动态ActionForm是为了避免标准ActionForm膨胀而设计的,使用动态ActionForm可以获得标准
ActionForm的所有功能
* 在struts-config.xml文件中定义动态ActionForm,如:
<form-beans>
<form-bean name="dynaForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="username" type="java.lang.String" />
<form-property name="age" type="java.lang.Integer"/>
</form-bean>
</form-beans>
*在Action中使用动态ActionForm,参见DynaActionFormTestAction.java 使用了DynaActionForm累中get的方法
DynaActionForm daf = (DynaActionForm)form;
String username = (String)daf.get("username");
Integer age = (Integer)daf.get("age");
注意:DynaActionForm是Struct1.x自带的一个类
动态ActionForm其实是把页面中的html元素的名字和值放到了map中,所以通过get方法可以取出相应的值
动态ActionForm采用EL表达式的输出方式,${dynabean.map.prop}, 参见:dyna_actionform.jsp
动态Action的验证,通常使用动态验证框架validator
2、采用struts上传文件
* 页面的配置,如:
<form action="upload.do" method="post" enctype="multipart/form-data">
标题:<input type="text" name="title"><br>
文件:<input type="file" name="myfile"><br>
<input type="submit" value="提交">
</form>
* ActionForm中使用FormFile来接收上传的文件,参见:UploadActionForm.java
* 在Action中调用FormFile取得上传文件数据,采用流输出,即完成上传,参见:UploadTestAction.java
* 采用<controller/>标签配置上传参数,如:<controller maxFileSize="10M"/>
3、空字段测试
* 在表单中没有input输入域,jsp脚本接收到的值为null,el表达式接收到的值为空串
* 如果表单中的值,没有输入,那么jsp脚本和el表达式接收到的值都为空串
4测试ActionForm类型的自动转换
* boolean:yes,1,on,true都会转换成True类型,而且忽略大小写,其他情况转换成false
* Date类型的转换:
* 如果是java.sql.Date,页面日期的格式必须为yyyy-mm-dd,才可以转换
* 如果是java.util.Date,默认情况下struts无法转换
* 自定义转换器的实现步骤
* 实现converter接口,实现convert方法
* 将实现的conerter注册,通常情况采用servlet注册
* 采用servlet注册需要注意标签的配置,<load-on-startup>10</load-on-startup>(也可以采用struts plugin注册)
Struts对ActionForm的自动搜集过程:
* 将页面数据放到map中,其中map中的key为页面中的名称,map中的value为页面中的value值
* 调用BeanUtils.setProperties方法,将map中的值逐个设置到ActionForm实例上,对于ActionForm中的每个属性
根据类型调用相应的Converter,然后调用相应的convert方法,将相应的字符串转换成ActionForm中指定的类型
可以通过BeanUtils.copyProperties(目标对象,源对象)方法进行对象值的复制。
5.ActionForward知识点复习
ActionForward的使用
1、理解全局和局部ActionForward的概念
2、redirect的使用
3、struts-config.xml文件不允许动态修改
4、理解动态ActionForward,动态的ActionForward是可以运行期修改的
6.ActionMapping的复习
1、struts-config.xml文件中,每个<action>标签对应一个ActionMapping实例
2、了解<action>标签中的forward和unknown属性的含义
3、了解采用jstl和struts标签保持页面数据
7. 分布数据
8.struts 国际化
Java中的国家化问题
1、了解缺省Locale是由操作系统决定的,Locale是由语言和国家代码组成
2、国际化资源文件是由baseName+locale组成,如:MessageBundle_en_US.properties
baseName是任意合法的文件名
3、native2ascii命令的位置和用法
* 位置:JAVA_HOME/bin
* 使用native2ascii.exe o.properties MessagesBundle_zh_CN.properties
4.
eg
Locale defaultl=Locale.getDefault();
System.out.println(defaultl.getCountry());
System.out.println(defaultl.getLanguage());
ResourceBundle r=ResourceBundle.getBundle("res.MessagesBundle", defaultl);
System.out.println(r.getString("k1"));
System.out.println(r.getString("k2"));
MessageFormat mf=new MessageFormat(r.getString("k1"),defaultl);
Object[] o={"wulinbo","早撒谎那个好"};
System.out.println("使用国际化处理(动态处理的国际化 )"+mf.format(new Object[]{"吴林波","早上好"}));
System.out.println("使用国际化处理(动态处理的国际化 )"+mf.format(o));
Struts国际化问题
概念区分
硬编码国际化(指的是静态中文转换为其他的一种语言)
动态编码国际化(是指的是程序在运行期间的代码的国际化,可以使用占位符)
1、struts国际化的配置
* 在struts-config.xml文件中加入:<message-resources parameter="MessageResources" />
2、提供不同版本的国际化资源文件,中文需要采用native2ascii转换成unicode
3、在jsp中采用<bean:message>标签来读取国际化消息文本
4、了解利用struts默认将locale放到session中的特性,完成采用编程的方式切换语言设置
* 参见:ChangeLanguageAction.java 如下
String language=request.getParameter("language");
Locale defaultl=Locale.getDefault();
if(language.equals("CN"))
{
defaultl=new Locale("zh","CN");
}
else if(language.equals("US"))
{
defaultl=new Locale("en","US");
}
//使用struts中的方法 是一种session HttpSession session =request.getSession()
//session.setAttribute("","");
request.getSession().setAttribute(Globals.LOCALE_KEY, defaultl);//import org.apache.struts.Globals;
//this.setLocale(request, defaultl);//使用Action中自己带的SetLocal来设置本地语言
return mapping.findForward("lanChange");
5、消息文本的国际化处理,共有三个步骤:
* 创建国际化消息
* 传递国际化消息
* 显示国际化消息
如何创建国际化消息?
理解ActionMessage和ActionMessages两个对象的区别
如何传递国际化消息?
* 调用saveMessage()传递普通消息,调用saveErrors传递错误消息
如何显示国际化消息?
通过<html:messages>标签显示消息(可以显示普通消息和错误消息)
通过<html:errors>
了解 使用JSTL标签中的fmt格式化标签来国家化
首先在.jsp文件的头文件上添加
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<fmt:setLocale value="${header['accept-language']}"/>
<fmt:setBundle basename="res.MessageResources"/>
其中properties文件放在res文件中
其次使用如下
<h1><fmt:message key="user.title"/></h1>
<hr>
<form action="login.do" method="post">
<fmt:message key="user.username"/>:<input type="text" name="username"><br>
<fmt:message key="user.password"/>:<input type="password" name="password"><br>
<input type="submit" value="<fmt:message key="user.button.login"/>">
</form>
struts异常处理
1、编程式异常
* 截获异常
* 创建相应的异常消息
* 传递异常消息
* 转向相应的页面处理异常
2、声明式异常(自动处理的异常)
* 在struts-config.xml文件中配置<exeception/>标签
* 理解局部和全局exception
* 注意局部<exception/>标签需要配置到<forward/>标签的前面,详见dtd中的约束
<exeception/>标签中的属性说明:
* key:指异常信息对应的国际化消息文本,这个key值需要在国际化资源文件中定义
* type: 处理那种异常
* path: 定义一但出现异常,需要转向那个页面,如果不定义path,
默认情况下将使用<action>标签中input属性对应的页面
* scope:可以取值request和session,默认为request
* handler:异常的处理类,struts默认采用org.apache.struts.action.ExceptionHandler,
如果做个性化的异常处理可以继承此类覆写相应的方法
参见:ErrorCodeExceptionHandler.java和AppExceptionHandler.java
DispatchAction应用
可以减少struts配置文件中的action量
如下例子:
配置文件
<action path="/user/userMaintent" type="edu.struts.actionextend.userAction" scope="request" parameter="command">
<forward name="add_success" path="/user/add_success.jsp" />
<forward name="del_success" path="/user/del_success.jsp" />
<forward name="modify_success" path="/user/modify_success.jsp" />
</action>
userAction类处理
主要是继承了dispatchAction 该类
public class userAction extends DispatchAction {
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
//return mapping.findForward("add_success");
return mapping.findForward("success");
}
public ActionForward del(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
//return mapping.findForward("del_success");
return mapping.findForward("success");
}
public ActionForward modify(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
//return mapping.findForward("modify_success");
return mapping.findForward("success");
}
}
jsp页面的请求处理
<h3>使用dispatchAction可以减少action 配置量(模式匹配)</h3>
<a href="user/ userMaintent.do?command=add">USER添加</a><br>
<a href="user/duserMaintent el.do?command=del">USER删除</a><br>
<a href="user/ userMaintent.do?command=modify">USER修改</a><br>
struts模式匹配
<!--模式匹配-->
<action path="/user/*" type="edu.struts.actionextend.userAction" scope="request" parameter="command">
<!-- <forward name="success" path="/user/{1}_success.jsp" /> -->
<forward name="success" path="/{0}_success.jsp" />
</action>
<h3>使用dispatchAction可以减少action 配置量(模式匹配)</h3>
<a href="user/add.do?command=add">USER添加</a><br>
<a href="user/del.do?command=del">USER删除</a><br>
<a href="user/modify.do?command=modify">USER修改</a><br>