- 浏览: 887566 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
转自http://javaee-dev.iteye.com/
Day1:
overview:
1.MVC概述
2.Struts框架 (技术概览)
3.Struts开发步骤
4.Struts新手上路
5.Struts详解
6.使用工具构建struts应用
**************************************************************
一 MVC概述 (教材Page 219)
1 起源
2 设计理念
图(Page 219)
Controller:
Model:
View:
3.分层设计对Model的影响
4.Web MVC的发展(Page 221 ~ 227)
Model1 ---> Model2 ---> Framework
1)Model1的特点(Page 222)
2)Model2的特点(Page 224)
3)Framework的引入(Page 226)
引入框架的作用
A. 使得功能组件松散耦合,甚至可配置
B. 提供公用的服务:
例如:i18n,安全,表单的重复提交,文件上传……
C. 简化开发模型——使得开发人员的精力集中在业务逻辑之上
框架的分类
A.设计的思路
白盒框架:使用时,需要了解其内部结构(extends);入侵性框架
黑盒框架:不需了解其代码细节,最多实现其接口;非入侵性框架
B.功能、作用
Web:Strusts1.x, WebWork, Strusts2.x(发展1.x和webwork), JSF(抗衡.net), Tapestry,
Shale, ZK, Echo, (根本全是Servlet规范) ……
Business:Spring, Seam
Persistence(持久层):Hibernate, Toplink, OpenOJB, ……
评价框架的优劣?
A.设计理念 先进?
B.编程模型 简单?
C.是否拥抱规范、标准?
D.社区是否庞大?第三方的支持程度?
程序设计思路
可维护性:预见需求(预见多年后的事)
可重用:
代码可重用(最低级别):粒度:方法(常用代码块),类,包,组件(类库)
设计的可重用:框架(半成品,如Hibernate);产品(开发软件);算法、设计模式
分析的可重用(最高级别,见不到代码):文档、规范、标准(ISO:CMM,CMMI)
可扩展性:
*****************************************************
二、Struts框架 (技术概览)
1.Struts简介
Apache
OpenSource
官方网站:http://jakarta.apache.org
MVC
Servlet, JSP, 资源文件, 定制标签库
Struts框架的位置
2.Struts快速上手
需求描述:
系统的登录
开发步骤
1) 创建项目、搭建环境
下载Struts开发包
把%STRUTS_HOME%/lib/*.jar拷贝到WEB-INF/lib
把%STRUTS_HOME%/contrib/struts-el/lib/*.jar拷贝到WEB-INF/lib
把%STRUTS_HOME%/lib/*.tld拷贝到WEB-INF(新版本无需这么做)
将%STRUTS_HOME%/contrib/struts-el/lib/*.tld 拷贝到WEB-INF(新版本无需这么做)
2) 配置WEB-INF/web.xml文件
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3) 在WEB-INF创建struts-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans />
<global-exceptions />
<global-forwards />
<action-mappings />
<message-resources parameter="com.yourcompany.struts.ApplicationResources" />
</struts-config>
4) 提供login.jsp
引入struts标签库
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html:form action="/login">
<table>
<tr>
<td>用户名:</td>
<td><html:text property="username"></html:text></td>
</tr>
<tr>
<td>密 码:</td>
<td><html:password property="password"></html:password></td>
</tr>
<tr>
<td colspan=2 align=center>
<html:submit value="登录"></html:submit>
</td>
</tr>
</table>
</html:form>
5) 提供Form Bean
com.form.LoginForm
public class LoginForm extends ActionForm {
private String username;
private String password;
//getter, setter
}
配置文件更新:
<form-beans>
<form-bean name="loginForm" type="com.form.LoginForm"></form-bean>
</form-beans>
6) 提供action:LoginAction extends Action
public class LoginAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginForm loginForm = (LoginForm)form;
String username = loginForm.getUsername();
String password = loginForm.getPassword();
boolean isLogin = false;
if("maxwell".equals(username) && "123".equals(password)) {
isLogin = true;
}
if(isLogin) {
return mapping.findForward("success");
} else {
return mapping.findForward("error");
}
}
}
配置文件更新:
<action-mappings>
<action path="/login" type="com.action.LoginAction" name="loginForm">
<forward name="success" path="/success.jsp"></forward>
<forward name="error" path="/error.jsp"></forward>
</action>
</action-mappings>
3.Struts技术详解
1) struts的MVC模型 (Page229)
2) 主要组件详解
1)ActionServlet
继承HttpServlet类,需要在web.xml中配置
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2)Action
开发人员必须继承这个Action类,供ActionServlet所驱动。
职责:调用业务逻辑方法
将控制权返回给ActionServlet并且提供相关的路由信息
public class LoginAction extends Action {
......
}
步骤:
(1) 继承Action类。
(2) 覆盖 execute(...)方法。
(3) 返回ActionForward对象 (提供决策信息给ActionServlet选择适当的视图响应用户) 。
(4) 在struts-config.xml中配置
<action-mappings>
<action input="/index.jsp" :ActionForm验证失败的跳转页面
name="aForm" :与Action对应的FormBean对象
path="/myAction" :请求URI(/myAction.do)
scope="session" :FormBean作用域范围
type="action.LoginAction" :自定义的Action类
validate="true" :FormBean是否调用validate(...)方法
>
<forward name="success" path="/success.jsp" /> :成功跳转的页面
</action>
......
</action-mappings>
注:scope的值可以是request和session,默认是session
3)ActionForm:封装HTTP请求中的数据
将用户提交的数据自动填充(在相应的action的execute方法被调用之前)到form的属性中
无需手工调用request.getParameter(…)
开发人员必须继承这个ActionForm类
public class LoginForm extends ActionForm {
......
}
3) 处理流程(程序中的关系)
****************************************************************************
三、使用IDE工具生成struts项目
Day2:
1 视图选择
2 国际化
3 Struts中的异常处理
4 动态表单
5.标签库
*************************************************************************
1 视图选择
局部转发与全局转发(优先级:局部转发的优先级比全局转发的优先级高)
1) 局部转发:只对某个Action可见
<action ...>
<forward name="success" path="/success.jsp" />
</action>
2) 全局转发:对所有的Action可见(共享)
<global-forwards>
<forward name="success" path="/globalsuccessful.jsp"></forward>
</global-forwards>
例子:
把登录例子中的成功跳转设置为全局转发。
2 I18N
I18N解决办法
创建多个资源文件,根据用户设置选择不同资源文件
ApplicationResources.properties
ApplicationResources_en.properties
ApplicationResources_zh.properties
资源文件:
用于映射页面中的静态信息、按钮标签、错误信息等,
通过一个属性文件(.properties) 把所有页面的静态信息集中在一起,便于修改。
例子:
编写资源文件的步骤:
1) 编辑资源文件
login_en.properties
login.title=Login Page
login.success=Congratuation! You successfully login our System!
login.username=User Name
login.password=Password
添加对中文的支持txt:
login.title=登录页面
login.success=恭喜你!你已经成功登录我们的系统了!
login.username=用户名
login.password=密码
login.submit=登录
转换本地编码为Unicode:
native2ascii login.txt login_zh.properties ----->生成login_zh.properties文件
login.title=\u767b\u5f55\u9875\u9762
login.success=\u606d\u559c\u4f60\uff01\u4f60\u5df2\u7ecf\u6210\u529f\u767b\u5f55\u6211\u4eec\u7684\u7cfb\u7edf\u4e86\uff01
login.username=\u7528\u6237\u540d
login.password=\u5bc6\u7801
login.submit=\u767b\u5f55
2)在struts-config.xml文件中配置资源文件<message-resources parameter="login" />
3)在JSP文件中使用<bean:message key="login.title"/>标签输出资源文件中的值
4)演示效果:
修改浏览器的设置
英文界面少写了"login.submit";则是找出中文的
3 Struts中的异常处理
java class: try/catch/finally/throws/throw/custom Exception class
jsp: page指令 + web.xml配置<error-page>
struts: try/catch/finally/throws/throw/custom Exception class
声明方式(*)------->struts-config.xml
定制异常处理器(*)
ActionErrors(或ActionMessages):异常的集合类
ActionMessage:具体异常类
关系图
方法一:
在actionform的validate方法中处理(很少使用,一般用验证框架实现用户输入合法性验证)
(1)重写action form的validate方法
@Override
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if(username == null || username.equals("") || username.length() > 50) {
ActionMessage msg = new ActionMessage("error.username");
errors.add("errorusername", msg);
}
return errors;
}
login_en.properties的内容
error.username=Please input the correct user name!
login_zh
error.username=请输入正确的用户名信息!
error.username=\u8bf7\u8f93\u5165\u6b63\u786e\u7684\u7528\u6237\u540d\u53ca\u5bc6\u7801\uff01
(2)配置struts-config.xml文件
在action标记内添加一个input属性和validate属性
其中,
input属性的值-----表示发生错误后跳转到的页面
validate属性的值-----表示ActionServlet是否去执行ActionForm的validate(...)方法,并且这个属性默认值是true
<action-mappings>
<action name="loginForm"
path="/login"
type="com.action.LoginAction"
input="/login.jsp"
validate="true">
<forward name="fail" path="/fail.jsp"></forward>
</action>
</action-mappings>
(3)在login.jsp页面中加入<html:errors/>输出错误。
方法二:
在action的execute方法中处理(极少使用,知道这种方法就可以了)
(1)在action的execute方法中写错误处理的代码(和action form里valdiate方法的代码基本一致)
例如:
对于登录用户例子----把narci的都列为黑名单。
Action:
ActionMessages errors = new ActionMessages();
if("narci".equals(loginform.getUsername())) {
System.out.println("narci");
ActionMessage msg = new ActionMessage("error.user.blacklist");
errors.add("blacklist", msg);
this.saveErrors(request, errors);
return mapping.findForward("current");
}
(2)
//比在form的validate方法多出的一步
saveErrors(request, errors);
return mapping.findForward("current");
并且在struts-config.xml中配置
<forward name="current" path="/login.jsp"></forward>
login_en.properties加入内容
error.user.blacklist=this user in blacklist!
login_zh
error.user.blacklist=该用户已被列入黑名单!
正式的: error.user.blacklist=\u8be5\u7528\u6237\u5df2\u88ab\u5217\u5165\u9ed1\u540d\u5355\uff01
(3)
<html:errors/>---->用于页面中显示异常信息(通过资源文件映射)
方法三:
通过抛出异常处理错误(推荐使用:处理业务逻辑方面出现的错误)
(1)在action的方法中抛出异常
(2)在struts-config.xml声明该异常的处理方法(通过exception标记) 局部异常
<action-mappings>
<action name="loginForm"
path="/login"
type="com.action.LoginAction"
input="/login.jsp"
validate="true">
<exception key="errors.noauthorization"
type="com.exception.NoAuthorizationException"
path="/noauthorization.jsp">
</exception>
<forward name="fail" path="/fail.jsp"></forward>
<forward name="current" path="/login.jsp"></forward>
</action>
</action-mappings>
key="errors.noauthorization" 异常提示信息仍然通过资源文件作映射
path="/noauthorization.jsp" 出现异常时的处理页面
type="exception.NoAuthorizationException" Action处理业务过程中有可能出现的异常类型
资源文件加入:
errors.noauthorization=no authorization
errors.noauthorization=当前用户没有授权!
全局异常(对所有的action共享的,所以优先级应该比较低)
<global-exceptions>
<exception key="errors.global" type="java.lang.Exception" path="/error.jsp"></exception>
</global-exceptions>
资源文件加入:
errors.global=System Error! Please contact our administrators!
errors.global=系统错误!请联系管理员!
在LoginAction中加入
if("admin".equals(loginform.getUsername())
&& "".equals(loginform.getPassword())) {
throw new Exception();
}
4 动态表单
可以减少ActionForm的数量,完成对html form属性的动态映射,更便于应用维护。
实现动态表单功能:通过struts-config.xml配置
<form-beans >
<form-bean name="dynForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="name" type="java.lang.String"></form-property>
<form-property name="age" type="java.lang.String"></form-property>
<form-property name="city" type="java.lang.String"></form-property>
<form-property name="gender" type="java.lang.String"></form-property>
</form-bean>
</form-beans>
<action-mappings >
<action name="dynForm"
path="/enroll"
scope="request"
type="com.tarena.struts.action.EnrollAction" >
<forward name="success" path="/success.jsp" />
<forward name="fail" path="/fail.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.tarena.struts.ApplicationResources" />
Struts中表单使用技巧:
1)同类型或结构相近的html form通过一个ActionForm类型映射
2)在都能满足需要的前提下,尽量使用动态表单
3)ActionForm的作用域范围应尽量小,对于存放在session中的ActionForm,当不再使用时应销毁
4)ActionForm主要用于控制器与视图之间传数据,不应包含任何业务逻辑
Struts 标签
************************************************************************************************
一、Struts标签库概述
1.回顾已经学了JSTL标签库
标签库的作用:
1.使得(jsp)页面开发人员不再依赖Java(EL表达式的作用也是如此)
2.功能封装:可重用
2.Struts的五类标签库
Bean Tags :用来创建bean、访问bean
HTML Tags :用来创建 html 页面的动态元素,对html进行了封装;
Logic Tags:逻辑判断、集合迭代和流程控制。
Nested Tags:该标签库建立在前三个标签库的基础上,具有前三个标签库的所有功能,只是允许标签间的嵌套。
Tiles Tags :该标签库包含的标签可以用来创建tiles样式的页面;布局专用。
3.重点学习前3类标签库
二、Bean标签
可以看成 <jsp:useBean> 的增强版,
它可以定义bean :获取某些数据(cookie,请求参数,请求头),将之定义成一个脚本变量,并同时置于某个作用域(缺省pagaContext) 中;
bean标签的公共属性:
id - 定义一个变量
name - 引用一个存在的bean或对象的名字
property - 被引用的bean的属性
scope - 放置或搜索bean的范围,若没有制定,则依次 page--request---session--application
1.<bean:define/>
作用: 把一个bean 或其属性, 定义成一个变量
* 通过<bean:define/>定义的变量可以通过JSP脚本、EL以及Struts本身的<bean:write/>标记访问。
Example1:
1) 定义一个Java bean:student,并且对其属性进行赋值
2) 通过<bean:define/>定义stuName、stuAge、stuGender三个变量,将student这个对象的属性值赋值给这些变量
<bean:define id="stuName" name="student" property="name"></bean:define>
<bean:define id="stuAge" name="student" property="age"></bean:define>
<bean:define id="stuGender" name="student" property="gender"></bean:define>
3) 输出
<%=stuName%> //jsp形式
${stuAge } //EL表达式
<bean:write name="stuGender"/> //Struts方式
* 如果JavaBean的属性是List等类型,可以指定type属性
Example2:
1)在Java Bean中添加List属性,并提供get/set方法。
private List songs;
public List getSongs() {
List list = new ArrayList();
list.add("我爱北京");
list.add("我和你");
list.add("我不做大哥好多年");
return list;
}
2)<bean:define id="songs" name="student" property="songs"></bean:define>
3)输出
${mySongs[0] }
* 定义新变量,例如:
<bean:define id="bookName" value="Effective Java"></bean:define>
2.<bean:write/>
作用: 输出 bean 或bean属性;
等价于:
${} 或者 <%= %>
3.<bean:message/>
作用:读取属性静态文本内容,支持国际化(i18n)
Example:
1)确认在类路径上含有
com/ApplicationResources.properties
配置路径: <message-resources parameter="com.ApplicationResources" />
2)在文件中加入key,value对
page.title=\u9875\u9762\u6807\u9898
3)提供message.jsp
使用<bean:message key="page.title"/>
4.<bean:size/>
作用:获得一个集合或者数组的大小
Example:
1)定义Java Bean : student
2)读取student这个java bean的songs的size
<jsp:useBean id="student" class="com.bean.Student"></jsp:useBean>
<bean:size id="songsize" name="student" property="songs"/>
3)输出songsize值
Exapmple:定义一个列表,输出其size,要求使用<bean:size/>获取该值
1)<%定义一个List,并初始化%>
2)使用 <bean:size id="listsize1" collection="<%=list %>"/> 获取值
注意:如果使用${},必须要把list放置到范围对象中
3)输出
5.<bean:cookie/>
作用:读取请求头中cookie的信息
* <bean:cookie id="cid" name="customid">
获得指定的名为 "customid" 的coockie,并将其赋值给脚本变量 cid
* 若找不到id为costCookie这个cookie,所以系统创建一个cookie,并将它的值设置为"uu11"
<bean:cookie id="cost" name="costCookie" value="uu11"/>
输出: <bean:write name="cost" property="value"/>
6.<bean:header/>
作用:获取请求头的属性信息
<bean:header id="userAgent" name="User-Agent"/>
//打印出:Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.8.0.7) Gecko/20061011....未完
<bean:header id="host" name="host"/>
//打印出:127.0.0.1:8080
<bean:header id="dummy" name="UNKNOWN-HEAD" value="no defined Header"/>
// no defined Header
7.<bean:include/>
作用:对指定url(由forward、href或page确定)处的资源做一个请求,
将响应数据作为一个String类型的bean绑定到page作用域,
同时创建一个scripting变量。我们可以通过id值访问它们。
Example:
1)在根目录下定义一个文件:include.txt
2)获取文件的内容数据,并赋于words
<bean:include id="words" page="/include.txt"/>
3)输出内容
8.<bean:resource/>
作用:获取指定的资源,以String或者InputStream的方式来读取,其中input属性是决定了对应的方式。
默认(false)是以字符串的方式来读取。
例如:
<bean:resource id="r1" name="/include.txt" /> //打印文件原内容: Hello World!
<bean:resource id="r2" name="/include.txt" input="true" />
//打印出:java.io.ByteArrayInputStream@735f45 input="false"时同样这打印
9.<bean:parameter/>
作用:取出url中queryString中指定参数名称的值
例子:
<bean:parameter id="target" name="action" />
只会读取第一个名字为"action"的参数
<bean:parameter id="ps" name="hobby" multiple="true" />
把url中queryString中名字叫hobby的所有值赋值给变量ps,所以ps应该是一个数组
10.<bean:page/>
作用:把pageContext中的特定的隐含对象(application, request, response, config, session) 取出来,
绑定到某个id中,本页的其他地方就可以使用id来操纵这些隐含对象了。
Example:
<bean:page id="res" property="response" />
<bean:page id="sess" property="session" />
<bean:write name="res" property="contentType"/>
<bean:write name="res" property="characterEncoding"/>
<bean:write name="sess" property="id"/>
<bean:write name="sess" property="maxInactiveInterval"/>
三、HTML标签库
使用taglib指令引入标签库
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
通常是配合bean标签一起使用,是struts中最常用的标签之一。
1.<html:form/>
作用:对html的form表单进行简单的封装,满足struts中表单请求的处理
<html:form action="/login">
</html:form>
如果你有上述一个标签,那么你的Struts配置文件的元素中必须有一个如下内容:
<action-mappings>
<action input="/login.jsp" name="loginForm" path="/login"
type="action.LoginAction" validate="true">
<forward name="success" path="/success.jsp" />
<forward name="error" path="/error.jsp" />
</action>
</action-mappings>
这就是说一个form标签是和form bean相关联的。
任何包含在<form>中用来接收用户输入的标签
(<text>、<password>、<hidden>、<textarea>、<radio>、<checkbox>、<select>)
必须在相关的form bean中有一个指定的属性值。<form>标签中method属性的缺省值是POST
2.<html:link>
作用:超文本连接
属性:page,指定一个页面的路径,必须以/开始。
Example:
当前页面跳转到/bean/parameter.jsp
需要提供参数:
<bean:define id="beanName" value="beanValue"></bean:define>
<html:link page="/bean/parameter.jsp"
paramId="action" paramName="beanName">
<html:param name="hobby" value="sports"></html:param>
跳转到bean:parameter.jsp
</html:link>
这等价于:
http://localhost:8080/工程名/bean/parameter.jsp?hobby=sports&action=beanValue
<a href="/工程名/bean/parameter.jsp?hobby=sports&action=beanValue">跳转到parameter.jsp</a>
3.<html:errors/>
作用:输出错误信息
异常处理会介绍
Example:
1)在资源文件中定义
property1.error1=Property1 Error1
property2.error1=Property2 Error1
property2.error2=Property2 Error2
property2.error3=Property2 Error3
property3.error1=Property3 Error1
property3.error2=Property3 Error2
globalError=Global Error
property1.message1=Property1 Message1
property2.message1=Property2 Message1
property2.message2=Property2 Message2
property2.message3=Property2 Message3
property3.message1=Property3 Message1
property3.message2=Property3 Message2
globalMessage=Global Message
messages.header=<table border=1><tr><td>错误变量</td><td>错误信息</td></tr>
messages.footer=</table>
2)添加jsp文件并编辑
<%@ page import="org.apache.struts.action.*"%>
<%@page import="org.apache.struts.Globals"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%
ActionMessages errors = new ActionMessages();
errors.add("property1", new ActionMessage("property1.error1"));
errors.add("property2", new ActionMessage("property2.error1"));
errors.add("property2", new ActionMessage("property2.error2"));
errors.add("property2", new ActionMessage("property2.error3"));
errors.add("property3", new ActionMessage("property3.error1"));
errors.add("property3", new ActionMessage("property3.error2"));
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("globalError"));
request.setAttribute(Globals.ERROR_KEY, errors);
ActionMessages messages = new ActionMessages();
messages.add("property1", new ActionMessage("property1.message1"));
messages.add("property2", new ActionMessage("property2.message1"));
messages.add("property2", new ActionMessage("property2.message2"));
messages.add("property2", new ActionMessage("property2.message3"));
messages.add("property3", new ActionMessage("property3.message1"));
messages.add("property3", new ActionMessage("property3.message2"));
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("globalMessage"));
request.setAttribute(Globals.MESSAGE_KEY, messages);
%>
3)输出相应的(出错) 信息:
<table border=1>
<tr>
<td>错误变量</td>
<td>错误信息</td>
</tr>
<tr>
<td>property1</td>
<td><html:errors property="property1" /></td>
</tr>
<tr>
<td>property2</td>
<td><html:errors property="property2" /></td>
</tr>
<tr>
<td>property3</td>
<td><html:errors property="property3" /></td>
</tr>
<tr>
<td>org.apache.struts.action.GLOBAL_MESSAGE</td>
<td><html:errors
property="org.apache.struts.action.GLOBAL_MESSAGE" /></td>
</tr>
<tr>
<td>All</td>
<td><html:errors /></td>
</tr>
</table>
<html:messages message="true" id="msg"
header="messages.header" footer="messages.footer">
<tr>
<td></td>
<td><bean:write name="msg" /></td>
</tr>
</html:messages>
4.<html:image>与<html:img>
作用:在页面中产生图像的输出
最重要的属性page:图象文件的路径,前面必须带有一个斜线。
其它属性:height、width(只有 img 可以设置长和宽)、alt(不知何用)。
Example:
<html:image page="/f4icmu.jpg" alt="软件工程之通俗版"></html:image>
<html:img page="/f4icmu.jpg"/>
等价于:
<input type="image" name="" src="/工程名/f4icmu.jpg" alt="软件工程详解">
<img src="/工程名/f4icmu.jpg">
5.<html:checkbox/>
生成一个checkbox。这里的value值可以是true,yes或on。
checkboxForm的属性:
private boolean one = false;
private boolean two = false;
private boolean three = false;
<html:checkbox name="checkboxForm" property="one">One</html:checkbox>
<html:checkbox name="checkboxForm" property="two">Two</html:checkbox>
<html:checkbox name="checkboxForm" property="three">Three</html:checkbox>
如果选中后被提交则相应的属性的值为true。
6.<html:radio/>
生成一个radio。主要的用法有两种。
下面的代码示例了html:radio标签的一般用法,
如果被提交则选中的radio的value值将被提交到radioForm中的id中。
<html:radio name="radioForm" property="id" value="00001"> One </html:radio>
<html:radio name="radioForm" property="id" value="00002"> Two </html:radio>
7.<html:select>标签和<html:option>标签
作用:对html中的下拉选择标签与选项标签做了封装
单选下拉
Example1:
<html:select property="singleSelect" size="3">
<html:option value="Single 0">Single 0</html:option>
<html:option value="Single 1">Single 1</html:option>
<html:option value="Single 2">Single 2</html:option>
</html:select>
Example2:性别
1)提供label和value的数组
<% String[] label = { "男", "女", "未知" };
String[] value = { "male", "female", "unknown" };
pageContext.setAttribute("label", label);
pageContext.setAttribute("value", value);
%>
2)标签使用:
<html:select property="sex" size="1">
<html:options labelName="label" name="value" />
</html:select>
Example3:兴趣爱好多选
1)提供列表
<% List options = new ArrayList();
options.add(new LabelValueBean("电脑游戏", "PCGame"));
options.add(new LabelValueBean("看电视", "TV"));
options.add(new LabelValueBean("阅读", "Reading"));
options.add(new LabelValueBean("唱歌", "Singing"));
pageContext.setAttribute("opt", options);
%>
其中,
public class LabelValueBean {
private String label;
private String value;
public LabelValueBean(String label, String value){}
}
2)提供多选标签
<html:select property="favors" multiple="true">
<html:options collection="opt" property="value"
labelProperty="label" />
</html:select>
Example4:联系方式多选
1)提供多选列表
<% List myPhones=new ArrayList();
myPhones.add(new LabelValueBean("小灵通","33213322"));
myPhones.add(new LabelValueBean("固话","80512010"));
myPhones.add(new LabelValueBean("手机","13711221113"));
pageContext.setAttribute("myPhones",myPhones);
%>
2)标签的使用
<html:select property="phones" multiple="true">
<html:optionsCollection name="myPhones"/>
</html:select>
8.<html:submit>标签
<html:submit value="Submit" />
9.<hmtl:text>标签
文本输入框
<html:text property="username" />
10.<html:password>标签
<html:password property="password"/>
11.<html:cancel/>取消标签
四、Logic标记 :
该标签库包含的标签可以用来进行逻辑判断、集合迭代和流程控制。
1.<logic:iterate/>
作用:<logic:iterate/>标签用来迭代集合
Example:
<%
List stuList=new ArrayList();
Student stu=new Student();
stu.setName("Alice");
...
stuList.add(stu);
request.setAttribute("stuList",stuList);
%>
<logic:iterate id="stu" name="stuList">
<tr>
<td>${stu.id }</td>
<td>${stu.name }</td>
<td>${stu.sex }</td>
<td>${stu.age }</td>
<td>${stu.desc }</td>
</tr>
</logic:iterate>
(2) logic:empty
用来判断是否为空的。如果为空,该标签体中嵌入的内容就会被处理。该标签用于以下情况:
当Java对象为null时
当String对象为""时
当java.util.Collection对象中的isEmpty()返回true时
当java.util.Map对象中的isEmpty()返回true时
下面的代码示例了logic:empty标签判断集合persons是否为空:
<logic:empty name="stu" property = "books">
<div>集合books为空!</div> </logic:empty>
logic:notEmpty标签的应用正好和logic:empty标签相反。
(3) logic:equal
这里要介绍的不只是logic:equal(=)标签,而是要介绍一类标签,这类标签完成比较运算,
包括:
logic:equal(=)
logic:notEqual(!=)
logic:greaterEqual(>=)
logic:lessEqual(<=)
logic:graterThan(>)
logic:lessThan(<)
Example:
<logic:equal name="stu" property="name" value="Alice">
I am Alice.
</logic:equal>
<bean:define id="count" value="168"/>
<logic:equal name="count" value="168">
Good lucky number.
</logic:equal>
Day3:
1 定制Action
2 禁止表单重复提交
3 定制Controller
4 验证框架
************************************************************************
1 定制Action
1) DispatchAction:可以将相关的一组操作放在一个Action类中(同一模块功能)
特点(优点) :
1)一个 Action可以对应多个业务方法(CRUD),而无需通过增加隐藏域的方式来处理。
2)避免Action类数量随业务复杂度而膨胀,可以共享公共的业务逻辑代码。
3)无需重写execute方法
4)DispatchAction类本身已经重写了Action类的execute方法。
实现DispatchAction的步骤:
1) 继承DispatchAction
SuperGileAction extends DispatchAction
2) 定义自己的处理方法,不要覆盖execute()方法
3) struts-config.xml中action元素增加parameter属性
<action path="/super" name="superForm" parameter="method"
type="com.tarena.action.SuperGileAction">
<forward name="success" path="/success.jsp"></forward>
</action>
用户请求URL应有如下格式:
a)Get方法
http://localhost:8080/super/SuperGileAction.do?method=<method_name>
b) Post方法
在表单中添加参数来完成
2) LookupDispatchAction:
特点:它是DispatchAction的子类,所以具备DispatchAction的所有特性,
支持一个表单对应多个业务方法。
实现LookupDispatchAction的步骤:
1) 继承LookupDispatchAction
2) 定义自己的处理方法,覆盖getKeyMethodMap()方法,不要覆盖execute()方法
getKeyMethodMap()完成资源文件中Key与Action中方法映射
@Override
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("submit.modify", "modify");
map.put("submit.add", "register");
return map;
}
public ActionForward modify(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response){
...
}
public ActionForward register(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response){
...
}
3)struts-config.xml中为Action增加parameter属性
<action path="/lookupAction"
name="superForm"
type="com.tarena.action.SuperGirlLookupAction"
parameter="method">
<forward name="success" path="/success.jsp"></forward>
</action>
4) 提交页面按钮有如下格式
html:submit的property属性值与Action中的parameter属性值映射
<html:submit property="method">
<bean:message key="submit.add"/>
</html:submit>
<html:submit property="method">
<bean:message key="submit.modify"/>
</html:submit>
3) Action编程技巧(建议) :
1)尽量避免使用实例变量或静态变量
(servlet是单实例多线程,所以要自己维护成员变量的同步问题)
2)使用自己的BaseAction完成Action的公共操作,其余Action可从BaseAction派生
3)Action不要代替Model工作
在设计多层架构时,使用Business Delegate可降低层与层之间的耦合度
2 禁止表单重复提交
1)客户端实现(JavaScript)
2)JSP实现(脚本)
图解
实现代码
3)Struts实现
(1)Struts内置实现,无需额外配置
(2)需要在前一个action的方法中调用saveToken()方法
saveToken(request);
(3)在后一个执行业务逻辑的方法中使用isTokenValid(request)判断表单是否被重复提交
if (isTokenValid(request)) {
// invoke business method
//......
// reset transaction token after transaction success!
this.resetToken(request);
return mapping.findForward("success");
} else {
System.out.println("duplicate token");
return mapping.findForward("error");
}
3 定制Controller(可选)
扩展控制器功能
ActionServlet与RequestProcessor的作用
1)继承RequestProcessor
2)通过processPreprocess()增加定制功能
//自定义控制器需要派生自RequestProcessor
package com.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.RequestProcessor;
public class SecurityRequestProcessor extends RequestProcessor {
@Override
protected boolean processPreprocess(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("start controller ...");
request.getSession().getServletContext().log("URL="+request.getRequestURL());//写日志
String ip = request.getRemoteAddr();
if (ip.equals("127.0.0.1")) {
System.out.println("valid client: 127.0.0.1");
return true; //只允许此IP登录
}
int lastPoint = ip.lastIndexOf(".");
String fourth = ip.substring(lastPoint + 1);
int fourthInt = Integer.parseInt(fourth);
if (ip.startsWith("192.168.1.") && fourthInt > 50 && fourthInt < 60) {
System.out.println("invalid client: 192.168.1.[50~60]");
return false; //限制黑名单IP的登录
}
return false;
}}
3)struts-config.xml中配置 <controller .../> (一般只有一个controller)
写在<action-mappings /> 之后;<message-resources .../> 之前
<controller processorClass="com.controller.SecurityRequestProcessor"/>
补充说明:
通常的一个struts-config.xml只能配置一个controller
一般地,在开发时通过定制controller来增强系统功能,例如:日志、安全限制等。
但在实际的应用中比较少使用。
举例:
public class SecurityRequestProcessor extends RequestProcessor {
public boolean processPreprocess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response){
String ip=request.getRemoteAddr();
if(ip.equals("127.0.0.1"))
return true;
int lastPoint = ip.lastIndexOf(".");
String fourth=ip.substring(lastPoint+1);
int fourthInt=Integer.parseInt(fourth);
if(ip.startsWith("192.168.1.")&&fourthInt>50&&fourthInt<60){
return true;
}
return false;
}
}
4 验证(校验) 框架
(1)有三种数据验证方式:
a.在ActionForm.validate() 当中进行
b.在Action.execute()方法中进行(这两种参看day2的异常处理,前两种)
c.引入validator框架(apache.jakata)
(2)声明式的数据验证(为什么能使用声明式?)--配置
原因:对于数据的验证有模式
(3)validator框架已经定义了一部分通用的验证规则和逻辑
开发者只需对特定数据指定具体的验证规则(业务)--使用
包含在validation.xml
使用验证框架的步骤:
1)在struts-config.xml配置校验插件(validate plugin)
放在<message-resources ../> 之后
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
注释:
1.验证插件:
1) validator-rules.xml :定义验证规则
规则名(如:required, maxlength.....)
验证方法
验证失败时出错提示(放到上下文中)
2)validation.xml
使用规则:对指定的表单属性进行校验
2.基本的结构:
1)验证逻辑:
validateXxx()方法
2)在validator-rule.xml中定义的都是校验规则
3)在validation.xml中(声明式验证)
a.引入了struts-config.xml的表单名字(form-bean的名字)
b.声明域的验证依赖规则
depends = "required,Integer"
2)add validator-rule.xml and validation.xml to /WEB-INF/
copy validator-rule.xml from struts framework
edit validation.xml
注意版本的一致
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
<formset>
<form name="enrollForm">
<field property="name" depends="required">
<arg key="register.name"/>
</field>
<field property="age" depends="required, integer">
<arg key="register.age"/>
</field>
<field property="city" depends="required">
<arg key="register.city"/>
</field>
<field property="gender" depends="required">
<arg key="register.gender"/>
</field>
<field property="email" depends="required,email">
<arg key="register.email"/>
</field>
<field property="birthday" depends="required, date">
<arg key="register.birthday"/>
<var>
<var-name>datePattern</var-name>
<var-value>yyyy-MM-dd</var-value>
</var>
</field>
</form>
</formset>
</form-validation>
注意:如果是使用1.3.x以上的版本,只需要引入:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml"/>
</plug-in>
validation.xml为:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd">
<form-validation>
<formset>
<form name="enrollForm">
<field property="name" depends="required">
<arg key="register.name"/>
</field>
<field property="age" depends="required, integer">
<arg key="register.age"/>
</field>
<field property="city" depends="required">
<arg key="register.city"/>
</field>
<field property="gender" depends="required">
<arg key="register.gender"/>
</field>
<field property="email" depends="required,email">
<arg key="register.email"/>
</field>
<field property="birthday" depends="required, date">
<arg key="register.birthday"/>
<var>
<var-name>datePattern</var-name>
<var-value>yyyy-MM-dd</var-value>
</var>
</field>
</form>
</formset>
</form-validation>
3)develop ur ActionForm (服务器端验证需要遵循的规范)
(1) 自定义ActionForm 要继承 ValidatorForm
最好不要重写validate方法!如果重写validate方法,则必须显式调用 return super.validate(...)方法
(2) 动态form要使用org.apache.struts.validator.DynaValidatorForm
4)(服务器端验证需要遵循的规范)
<action ..... validate="true" input="假如出错的页面" >
5)copy validation rules to ApplicationResources.properties
register.title=Super Boy Register Form
register.name=Name:
register.gender=Gender:
register.age=Age:
register.city=City:
register.email=Email:
register.birthday=Birthday:
errors.required={0} is required.
errors.integer={0} must be an integer.
errors.date={0} is not a date.
errors.email={0} is an invalid e-mail address.
6)active javaScript in Jsp page.(采用客户端验证才需要这一步)
<html:javascript formName="enrollForm"/>
<html:form action="/enroll" onsubmit="return validateEnrollForm(this)" method="post">
建议:(1) 客户端能做的验证,一般不要在服务器端验证。
一般输入格式等方面的验证
(2) 客户端实在没有能力进行验证的情况,发到服务器端做验证。
禁止表单重复提交:
1.客户端方案(Java Script)
使用js来实现禁止表单重复提交的方法很多,大体有如下几种:
1)提交时,使提交按钮不可用(disable),或者隐藏按钮,使用进度条
参考实现:
/*
函数名称:disableButtons
函数功能:提交前,将所有表单中的button,reset,submit禁用disabled;
如果是submit按钮,则添加与之相同隐藏文本框hidden对象,让提交的信息无一漏网
*/
function disableBtns()
{
for(k=0;k<document.all.length;k++ )
{
//当前节点对象
var obj = document.all(k)
if( obj.type=='button' || obj.type=='submit' || obj.type=='reset')
{
obj.disabled = true
if (obj.type=='submit')
{
//添加隐藏节点
var oNewNode = document.createElement("input");
oNewNode.type = "hidden"
oNewNode.name = obj.name
oNewNode.value = obj.value
obj.insertAdjacentElement("afterEnd",oNewNode);
}
}
}
}
/*
函数名称:disButtons2
函数功能:提交前,将所有表单中的button,reset,submit禁用disabled;
如果是submit按钮,则添加与之相同隐藏文本框hidden对象,让提交的信息无一漏网
函数说明:与上面的函数功能一样,但适用浏览器范围更广,推荐使用此函数。
*/
function disableBtns()
{
for(k=0;k<document.forms.length;k++ )
{
//获取当前表单
var frm = document.forms[k]
for(i=0;i<frm.length;i++)
{
var obj = frm.elements[i]
if ( obj.type=='button' || obj.type=='submit' || obj.type=='reset' )
{
obj.disabled = true
if (obj.type=='submit')
{
var oNewNode = document.createElement("input");
oNewNode.type = "hidden"
oNewNode.name = obj.name
oNewNode.value = obj.value
//frm.insertAdjacentElement("beforeEnd",oNewNode);
obj.insertAdjacentElement("afterEnd",oNewNode);
}
}
}
}
}
/*
函数名称:hiddenForm
函数功能:提交时让表单自动隐藏,而不影响数据的提交
*/
function hideForm(form)
{
//waitStr 提交过程中出现的提示,可以自行设置
var waiting = "<center><img src='progress.jpg'>数据正在提交中,请等候</center>";
form.innerHTML = "<div style='display:none;'>"+form.innerHTML+"</div>"+waiting;
}
2)使用标识来实现控制客户端多次点击
<script type="text/javascript">
//控制标志
var submitted = false;
function checkSubmit() {
if(submitted == true) {
alert("submitted == true");
return false;
}
submitted = true;
return true;
}
//控制页面双击行为
document.ondblclick = function docOnDblClick() {
window.event.returnValue = false;
}
//控制页面单击行为
document.onclick = function docOnClick() {
if(submitted) {
window.event.returnValue = false;
}
}
</script>
<html:form action="/logon" method="post" onsubmit="return checkSubmit();">
<html:text property="name"></html:text>
<html:submit value="login">
</html:submit>
</html:form>
2.服务器端方案
原理:使用transaction token
1)jsp版
Day4:
一、 文件上传
步骤:
1)定义表单
<html:form action="/fileupload" enctype="multipart/form-data">
<table>
<tr>
<td><b>请选择上传的文件:</b></td>
<td><html:file property="file"></html:file></td>
</tr>
<tr></tr>
&
发表评论
-
struts2 拦截器获取 request
2011-11-26 23:23 1041ActionContext actionContext = ... -
Struts2与DWR在项目中的共存解决方案
2011-09-10 22:35 894在struts2.properties中配置即可. strut ... -
Struts串讲
2011-02-11 10:40 1222Struts串讲 一、struts概述 1、Strut ... -
struts2 配置文件中,一个package中有多个name属性相同的action的执行
2011-01-26 08:53 1262如果在一个package中有多个name属性相同的action ... -
密码MD5加密及日期转换器
2010-10-26 10:21 2027今天继续学习bbs项目,汤老师讲了会员注册的实现,要对密码进行 ... -
传智播客erp项目学习,防止表单重复提交及MRP
2010-10-26 09:47 912今天结束了erp的学习, ... -
ActionForm的生命周期浅探
2010-10-21 12:48 1006看了很多的资料书籍,都提了一下ActionForm的生命周期。 ... -
Struts 1.x | <html> 标签库
2010-10-21 12:11 1761html标签库 生成html元 ... -
SSH项目中利用struts的ExceptionHandler处理异常
2010-10-13 17:25 1041一、概述 在Struts1.X的版本中加入 ... -
commons-beanutils包ConvertUtils使用(二)
2010-10-13 16:37 20171.org.apache.commons.beanutils. ... -
org.apache.commons.beanutils.ConvertUtils
2010-10-13 16:33 1362ConvertUtils,这个工具类的职能是在字符串和指定类型 ... -
透析struts中的redirect="true"与redirect="false"
2010-10-13 13:28 1724再struts-config.xml文件的forward下有个 ... -
struts-config.xml的controller 元素
2010-10-13 13:07 1315<controller>用于配置A ... -
防止刷新、重复提交
2010-09-06 10:33 745问题场景:在项目的添加方法中,添加完毕后,当用户再次刷新当前页 ... -
struts中ActionServlet核心处理RequestProcessor.process()
2010-08-29 17:04 1253public void process(HttpServlet ...
相关推荐
计算机软件编程学习笔记: 01. Unix note.txt 02. SQL note.txt 03. PL SQL note.txt ...14. Struts1.x note.txt 14. Struts2.x note.txt 15. Spring note.txt 16. EJB note.txt 17. WebService note.txt
14. Struts1.x note.txt 14. Struts2.x note.txt 15. Spring note.txt 16. EJB note.txt 17. WebService note.txt 18. English.txt 有朋友反映打开有些乱码,建议使用UltraEdit打开,可以无障碍使用. UltraEdit在我...
**Struts1.x note.jsp** 在Struts1的学习笔记中,`note.jsp`可能是用来展示或编辑用户笔记的页面。它可能包含Struts的标签库,如`<bean:write>`用于显示Form Bean中的属性值,或者`<html:form>`用于创建表单提交到...
Struts1.x note.txt`涉及到Struts1.x,这是一个早期的MVC(模型-视图-控制器)框架,用于简化JavaEE Web应用的开发。 5. **数据库交互**: - `08. JDBC note.txt`可能涵盖了Java Database Connectivity (JDBC),...
Struts1.x note.txt会讲解这个早期的MVC(Model-View-Controller)框架,它帮助组织Java Web应用的架构,提供动作调度、表单验证等功能。 这些笔记为全面学习Java及相关的Web开发技术提供了丰富的资源。通过深入...
Struts1.x note.txt`介绍了Struts1,这是一个早期的MVC(Model-View-Controller)框架,帮助开发者组织和管理Web应用程序的逻辑。 - `08. JDBC note.txt`涵盖了Java数据库连接,是Java访问数据库的标准接口,讲解...
Struts1.x note.txt**:Struts1是最早的Java Web MVC框架之一,笔记可能讲解Action、Form Bean、配置文件、Interceptor、Tiles组件等核心概念。 9. **16. EJB note.txt**:EJB(Enterprise JavaBeans)是Java EE中...
Struts1.x note.txt** - Struts 1是早期的MVC(模型-视图-控制器)框架,用于构建Java Web应用。笔记可能涵盖了ActionForm、DispatcherServlet、配置文件以及Struts的拦截器和异常处理。 9. **16. EJB note.txt** ...
14. Struts1.x note.txt涉及到Struts框架,这是一个早期的MVC(Model-View-Controller)框架,常用于构建企业级Java Web应用。虽然Struts 1现在已被更新的框架取代,但了解它的设计模式和工作原理对理解其他现代框架...
-------------------------------------------------------------------------------- 概述 软件包 类 使用 树 已过时 索引 帮助 上一个类 下一个类 框架 无框架 所有类 摘要: 嵌套 | 字段 | 构造方法 | 方法 ...
数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录 一个Java+ajax写的...