sshstruts2
Posted 白日梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sshstruts2相关的知识,希望对你有一定的参考价值。
1.b/s框架
browser-servlet请求-响应的处理过程的集合体
2.MVC模式(持久层,表示层,业务逻辑层)
M 数据模型(模型):作为程序的核心载体,用于传输数据(bean hibernate)
V 对外交互(视图):完成后对结果的展现(jsp struts2 )
C 程序的执行和控制(控制器):接受请求数据和处理请求(servlet spring)
3. model1模式和model2模式
Model1模式:整个web应用几乎全部是由jsp页面接受处理客户端请求的,对请求直接的作出响应 ,用少量的javabean来处理数据库连接,数据库访问等操作,Model1模式的实现较为简单,适用于快速开发小规模的项目,但是从工程化的角度看 它的局限性较为明显,jsp页面本身兼V和C两种角色,将表示层和业务逻辑层混杂在一起,从而导致代码的复用性较差,增加了拓展和维护的难度
Model2模式:MVC模式,servlet作为前端的控制器,负责接收客户端发送的请求 ,在servlet中只包含控制逻辑和简单的前端处理 ,然后调用后端的javabean来处理实际的逻辑,最后转发到相应的jsp页面处理显示逻辑 ,在model2下jsp不在承担业务逻辑,它仅仅是表现层角色,jsp页面的请求与servlet交互,而servlet负责与后台的javabean通信,在model2下模型由javabean充当,而业务逻辑由servlet承担
4 .http与java数据类型的区别
http属于弱数据类型,数据类型属于string,string【】类型,java属于强类型
5.web与struts2在线程安全方面的区别
Web容器是一个单实例的多线程环境,对于每个http请求,都会从线程池中分配一个线程,那么涉及到线程安全的并发问题(dopost方法,struts2也是一个单实例的多线程环境,但是通过threadlocal保证线程的安全
<filter>
<filter-name>action2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- END SNIPPET: filter -->
<filter-mapping>
<filter-name>action2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6.struts2的运行环境
struts2是以web环境为依赖,遵循servlet标准,通过实现filter接口进行http请求的处理,支持struts2的最低servlet版本是2.4相应的jsp最低版本是2.0版本,必须运行在jdk1.5版本上一样
7.struts2的运行原理
Struts2的核心模块分为两个部分 struts和xwork,struts只需要接受请求参数,然后交给xwork完成处理,当xwork执行完以后,返回相应的视图,xwork是struts2的执行核心, struts阶段是针对http请求预处理,这个阶段为业务逻辑执行必要的数据环境和运行环境做准备,通过dispatcher解耦,然后将程序执行的控制器移交给xwork,将http请求的数据封装成普通的java对象,并且由xwork负责执行具体的业务逻辑,这一阶段不再依赖于web容器,完全由xwork框架驱动整个执行的过程,其中Dispatcher起着关键的作用,http预处理以及尽可能的消除对web容器的依赖,将web容器与mvc分离 ,其中struts2的入口程序是filter拦截器(web.xml里面的filter配置),而Actionproxy是xwork框架的执行入口(配置文件的导入,dispatcher的处理),主要作用是屏蔽整个控制流元素的执行过程,对内的action等提供一个无干扰的执行环境(由threadlocal实现),而Actioninvocation 调度执行次序,他被封装在actionproxy的内部,然后通过Actioninvocation的对interceptor,action,result等调度执行,同时由actionproxy驱动执行,在这其中Interceptor与action的关系是一层包裹关系,一组interceptor环绕在action对象的执行切面,在action之前或者之后执行,从而实现对action的拦截作用,struts2仅初始化一次
8.访问servlet
方式1 Actioncontext类间接的获取
Getcontext方法 :静态方法,获取相应的对象实例
Get方法:返回object类型,该方法类似调用httpservletrequest的getattribute方法
Getapplication :返回map集合,模拟了servletcontext
Getparameters :返回map集合,相应的调用httpservletrequest的getparametermap方法
Getsession:返回map集合,模拟了httpsession方法
Setapplication:将一个map实例的key-value对转换成application的属性值和属性名
Setsession:与上类似
备注:Actioncontext作用域默认为request
方式2 接口 直接的获取
Servletcontextaware 直接访问web应用的servletcontext实例
Servletrequestaware获取相应的httpservletrequest实例
Servletresponseaware获取相应的httpservletresponse实例
其中相应的set方法中的参数指的是web应用对客户端的响应
方式3 工具类 Servletactioncontext的工具类 可以更加简单的获取
9.在 ValueStack 对象的内部有两个逻辑部分:
ObjectStack: Struts 把 Action 和相关对象压入 ObjectStack 中
ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中.实际上就是对 ActionContext 的一个引用
Struts 会把下面这些映射压入 ContextMap 中
#parameters: 该 Map 中包含当前请求的请求参数
#request: 该 Map 中包含当前 request 对象中的所有属性
#session: 该 Map 中包含当前 session 对象中的所有属性
#application:该 Map 中包含当前 application 对象中的所有属性
#attr: 该 Map 按如下顺序来检索某个属性: request, session, application
10.默认加载的xml配置文件及加载顺序
struts2-defalut.xml ,struts.xml,struts-plugin.xml
struts.xml用户自定义配置文件,
struts-default.xml 自带的配置文件,
struts-plugin.xml是struts2默认的插件配置文件
struts2配置文件的加载顺序 struts-default.xml---struts-plugin.xml---struts.xml
11. strus.xml配置文件介绍
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="id" extends="struts-default" >
<action name="login" >
<result>/success.jsp</result>
</action>
</package>
</struts>
Include节点:并没有在struts-default.xml中出现,可以写在struts.xml中,将整个应用配置根据一定的逻辑划分成若干独立的配置文件<include file=“...”/>
Version:版本
Encoding:编码
!doctype: xml文件的书写规范约束
Constant:默认配置在/org/apache/struts2/default.properties 下 说明见备注
Package:包
Package的包属性:
Name:包称
extends:继承的配置文件(通常都必须之间或者间接的继承struts-default)
12. package继承struts-defaul的简要说明
Namespace : 可选 默认为“/” 根命名空间
Action属性
name :action名
class: 可选 拦截处理类,默认为 actionsupport类
method: 可选 相应处理类方法名(默认execute)
result 属性
Type 可选 默认为dispatcher(转发) 详情见备注
Name:可选 相应action的method的return 默认为success
Result的子标签param(见结果处理):指定逻辑视图对应的实际视图资源
<default-interceptor-ref name="defaultStack"/> 默认使用的拦截器栈为defaultStack
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
说明:默认使用的action为com.opensymphony.xwork2.ActionSupport(书写时action没有写继承actionsupport会默认的继承actionsupport)
<global-allowed-methods> execute ,input ,back ,cancel,browse ,save,delete,list,index </global-allowed-methods>
说明:默认能够接受的方法为execute , input , back , cancel, browse , save, delete, list, index(否则需要相应的添加)
interceptor-stack说明见备注
都可以在Struts中更改
13. 以pojo作为载体的优点(javabean)
Javabean作为一个强类型(javabean:对象的产生主要是为了强调对象内在的特性和状态,同时构造一个数据存储和数据传输的载体)
2)Pojo不依赖任何框架,可以运行在程序的任何一个层次
3)Pojo突破了formbean(struts1中的数据载体)对页面元素唯一对应的限制,我们可以将一个页面中的元素自由映射到多个pojo中去
14. web与strust2的交互关系
1)对应关系
Httpservletrequest对应requestmap
Httpsession对应sessionmap
Servletcontext对应applicationmap
web原生的httpsession等不是线程安全的,struts2是线程安全的,这是由于threadloacl导致的
2)访问servlet的方式
方式1 采用Actioncontext类间接的获取
Getcontext方法 :静态方法,获取相应的对象实例
Get方法:返回object类型,该方法类似调用httpservletrequest的getattribute方法
Getapplication :返回map集合,模拟了servletcontext
Getparameters :返回map集合,相应的调用httpservletrequest的getparametermap方法
Getsession:返回map集合,模拟了httpsession方法
Setapplication:将一个map实例的key-value对转换成application的属性值和属性名
Setsession:与上类似
方式2 采用接口的方式直接的获取
Servletcontextaware 直接访问web应用的servletcontext实例
Servletrequestaware获取相应的httpservletrequest实例
Servletresponseaware获取相应的httpservletresponse实例
其中相应的set方法中的参数指的是web应用对客户端的响应
方式3 采用Servletactioncontext的工具类获取相对较为简单
15. objectfactory类
允许程序员在程序的运行期动态的添加一个新的对象,并且为新的对象实施依赖注入,使执行对象都受到xwork容器的管理,也是bean与struts2的内置对象进行对话的接口
其中的工具方法可以分为两类
1)有用构建内部对象的action,interceptor(aop),result,validator的快捷方法
2)另一类是用于构建一个普通bean的核心方法buildbean(ioc),buildbean包含了对象的创建和依赖注入两个核心的过程
16. Objectfactory与Container区别
Container:在初始化的时候被创建出来,主要保证运行期对已知定义好的内置对象的需求,所以以取为主
Objectfactory:偏重于程序运行的过程中对象的构建,以建为主
17. Valuestack与actioncontext关系
Actioncontext:是一个map集合,通过键和值来存储关系,数据共享,由于threadlocal不会导致线程安全问题
Valuestack是xwork用以对ognl的计算拓展的一个特殊的数据结构,是一个栈的数据结构,并且具备表达式计算的数据结构
Valuestack与actioncontext的关系:Actioncontext无法脱离valuestack而单独存在,否则pojo数据无法相应的传输,Valuestack离开actioncontext只有pojo数据的传输而没有pojo数据,valuestack的数据是从属于Actioncontext的
Valuestack又分为两个部分
Map栈:实际上ognlcontext类型,同时也是一个map,也是对actioncontext的一个引用 里面保存着各种map(Requestmap sessionmap applicationmap parametersmap ,attr)
对象栈:实际上是compoundroot类型,使用arraylist定义的栈(加入了相应的peek,push,pop方法),里面保存着当前action实例相关的对象,是一个数据结构意义的栈
18. actionsupport类
Action的一个默认的实现类,该方法已经提供了许多默认的方法,包含国际化信息方法,数据校验的方法等等,从而大大的简化了action的开发,做验证等时继承即可
Gettext(“key”,args)方法 可以访问本地化消息
19. action的动态方法调用Struts.xml
<struts>
<!--设置是否允许使用!-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="id" extends="struts-default" >
<action name="login" class="test1.Person" >
<result>/success.jsp</result>
<!—添加能处理的method方法-->
<allowed-methods>error,success</allowed-methods>
</action>
</package>
</struts>
Action类
public class Person extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String success() throws Exception {
System.out.println(1111);
return "success";
}
public String error() throws Exception {
System.out.println(222);
return "success";
}
@Override
public String execute() throws Exception {
System.out.println(333);
return "success";
}
}
Jsp
<form action="login.action" method="post">
user:<input type="text" name="name" >
<input type="submit" value="提交">
</form>
使用方法 在浏览器中输入http://localhost:8080/test1/login!error.action
注意:在struts2.3.4以下如果设了默认Action,再进行动态调用Action,会出现错误,在struts2.3.4以上就不会发生错误。
20.action的通配
<action name=”*_*” class=”test.{1}” method=”{2}”>
<result name=”{2}”>
{1}.jsp
</result>
</action>
{1}代表第一个* {2}代表第二个* 其他同理
匹配的优先级:没有使用通配的action名优先于有使用通配的action名,有使用通配的action名,没有先后顺序依次向下运行
21. 结果的处理
<global-results..>和<result..> 前者为全局 后者为局部
属性
Name:属性指定所配置的逻辑视图名
Type:属性指定的结果类型
常用的类型如下
Dispatcher和direct:上述已说明
Dispatcher和direct的子标签param允许的值为
location:指定逻辑视图对应的实际视图资源
parse:指定是否允许在实际视图中使用ognl表达式,默认值为true
<action name="login" class="test1.Person" >
<result type="dispatcher">
<param name="location">/success.jsp</param>
<param name="parse">true</param>
</result>
</action>
可以简写为
<action name="login" class="test1.Person" >
<result>/success.jsp</result>
</action>
说明:
redirectaction和chain的子标签param的允许的值为
actionname:重定向的action的名称
namespace:重定向需要指定的action所在的命名空间
<result name="input" type="chain">
<param name="actionName">login</param>
<param name="namespace">/test</param>
</result>
上述可以相应的简写为
<result name="input" type="chain">login</result>
<package name="test" namespace="/test " extends="struts-default">
<action name="login"
class="test.TestAction">
<result>/success.jsp</result>
</action>
</package>
参数的读取
#attr 例如<s:property value="#attr.name" />
22. Preresultlistener监听器
在action处理完之后转入实际视图之前被回调
public String execute() throws Exception {
//获取任务调度器
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
//调度addPreResultListener方法
invocation.addPreResultListener(new PreResultListener() {
// resultCode ;类似execute的return的值
@Override
public void beforeResult(ActionInvocation invocation, String resultCode) {
System.out.println(resultCode);
invocation.getInvocationContext().put("extra", resultCode);
}
});
return "success";
}
23. 异常处理机制1)异常的捕捉
方式1 try…catch…这种方法不便于维护
public String execute() throws Exception {
try {
} catch (Exception e) {
return "结果1";
}
return "结果n";
}
}
方式2 :在默认的拦截器栈中包含exception,进行异常拦截处理,只需要在相应的action中配置<exception-mapping result="…" exception="……"></exception-mapping>
或者在全局中配置即可
<global-exception-mappings >
<exception-mapping result="" exception=""></exception-mapping>
</global-exception-mappings>
Exception:指定该异常映射所设置的异常类型
Result:指定的action异常出现时,异常映射对应的逻辑视图
2)异常视图的输出
可以用ognl表达式
<s:property value=”exception”/> 显示异常对象
<s:property value=”exception.message”/>显示异常的message信息
<s:property value=”exceptionStack”/>输出异常堆栈信息
也可以用el表达式
${ exception } ${ exception.message } ${ exceptionStack }
24. convention插件(约定大于配置)
1)说明
convention插件支持0配置,不需要使用struts.xml文件进行配置,也不需要使用annocatation进行配置,而是由struts2根据约定来指定配置
2)convention插件需要导入的包:
struts2-convention-plugin包
3)搜索范围
convention会搜索位于action,actions,struts,struts2包下的java类,同时convention产检会把所有实现了action接口的java类和类名以Action结尾的java类当成action处理
4)convention插件允许设置的三个常量
struts.convention.package.locators:convention插件使用该常量指定的包作为搜寻的action的根包。例如actions.test.LoginAction 原本需要映射到/test/ LoginAction,但是指定为test,那么action将会映射到/login
struts.convention.exclude.packages:指定不扫描哪些包下的java类
struts.convention.action.packages:指定扫描的包,可以指定多个包
说明:在找到合适的action类之后,那么这些包下的子包则会相应的生成对应的命名空间
5)Action的name属性规则
1. 如果该action类名包含action后缀,将该action类名的action去掉,否则不做任何处理
2. 将驼峰命名法转换中划线写法
例如actions.test.LoginAction将映射到如下的url :/test/login 后缀的action被去掉了,如/test/login提交表单时,会交给actions.test.LoginAction处理
6)映射到相应的result
语法:actionname+resultcode+suffix
例如 action的url为/login 返回的逻辑视图名为success 结果类型为dispatcher 对应的视图为…login-success.jsp/html 或者是…login.jsp/html;
Action的url为/test/get-book 返回的逻辑视图名为success,结果类型为freemarker,对应的视图为… estget-book-error.flt velocity对应的suffix是.vm
7)利用config-browser插件查看应用中部署的action
config-browser插件的首地址为web_context/config-browser/index.action;
我们单机的为将web_context改为http://localhost:8888/convention即可
这个产电对struts和convention均有效,也就是说不是为convention的配置的
8)Action链的约定
1. 第一个action返回的逻辑视图字符串没有对应的资源
2. 第二个action需要在第一个action的同一个包下
3. 第二个action映射的url为firstactionname+resultcode
4. 例如第一个类名为firstAction 返回的逻辑视图为second,那么第二个类的类名为firstSecondAction
9)Convention的动态刷新
Convention在action或者jsp页面改变时,都是要动态的刷新页面,所以需要进行相应的配置<constant name=”””’struts.devMode” value=“true”/> <constant name=’”struts.classes.reload” value=””true”/> 不大建议使用,会相应的降低运行效率
还有一些其他的配置常量由于较少
注解方式:
略
25. 国际化
1)构建
1.全局需要设置的配置常量<constant name="struts.custom.i18n.resources" value="名称"></constant> 局部指定可以采用<s:i18n…/>标签,指定相应的国际化资源文件
2. 需要的文件 名称.properties,可以设置相应系列的国家的语言 名称_en_US.properties, 名称_zh_CN.properties等,底层基于web的国际化(见web国际化的resourcebundle),放置于src下
2)国际化资源的访问
可以采用相应属性key读取 例如:<s:>中的key ,-validation.xml中的message中的key
3)不同语言的设置方式
1改变浏览器的语言
2添加参数request_locale=语言_国家 例如request_locale=en_US
3局部指定可以在采用<s:i18n…/>标签,在其中指定相应的request_locale=语言_国家
4)占位符的设置填充
1设置
可以从{0}-{9} 在文本中的ognl表达式以${}表示 例如${expr}
2 填充
可以在相应的<s:>下使用<s:param../>标签来填充占位符,第一个对应第一个占位符,第二个代表第二个占位符,依次同理
在action中填充国家化占位符,则可以使用gettext(String atextname ,list args)或者gettext(String key ,String【】 args)来填充占位符,相应的list或者数组的第一个元素填充第一个占位符
5)错误消息的国际化设置
方法1:
在相应的action中添加gettext方法,当不符合条件是在采用addfielderror中添加相应的错误消息
方法2:
采用继承FieldValidatorSupport的方式,且在同包下书写classname-validate.xml,及在i18n中写相应的消息,见自定义拦截器
说明:struts2的拦截i18n实现
使用连接的方式设置
<a href="testin8n.action?request_locale=en_US">English</a>
<a href="testin8n.action?request_locale=zh_CN">中文</a>
以上为自动注入的方式,有相应的拦截器注入i18n
26. 类型转换
1)内置类型转换器
boolean char int long float double date 数组 集合
2)自定义类型转换器
1.需要继承或者实现的接口
备注:当转换为null时,那么会自动转为Objectfactory类
自定义转换类必须实现的接口是typeconverter接口,但是typeconverter接口过于复杂,所以实现类defaluttypeconverter的子类StrutsTypeConverter来实现自定义转换器
2.StrutsTypeConverter类
方法
convertFromString(Map arg0, String[] arg1, Class arg2):转换为对象
convertToString:对象转为string
定义全局类型的转换器
全局起作用需要提供一个xwork-converter.properties文件中,书写方式如java.util.Date=struts.DateConverter,放在同类的包下,局部类型转换器同包下无需写类名,classname-conversion.properties,书写方式如birthday= struts.DateConverter
3.类型转换错误处理
Conversionerror拦截处理转换类型错误,当转换错误,strurts2会将请求导向到input结果代码映射的视图
4.错误信息的设置
通常错误放在i18n消息键的xwork.default.invalid.fieldvalue=xxxx来报告消息错误,在消息中可以相应占位符使用字段名来填充,需要用constant指定,如果是局部的那么需要在同包下建立同类名的properties文件,书写方式如invalid.fieldvalue.user=u9519u8BEFu7684u8F93u5165u683Cu5F0F.
5.自定义转换器需要的文件,src下xwork-converter.properties或者同类包下classname-conversion.properties 继承StrutsTypeConverter的类,同包下建立同类名的properties文件指定错误消息
6.类型转换注解
略见struts2深入详解-323页(盘多多有下载)
类型的转换为了简洁一般继承actionsupport类
27 validatexxx方法和validate方法
1.可以使用validatexxx方法,xxx第一个字符大写的方式验证,这个方法由框架自动调用,这个方法不需要有返回值,如果验证错误,会直接将它添加到action的字段错误中,具体是由com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor拦截器的DefaultWorkflowInterceptor类的dointercept方法中对其调用的,
public void validateExecute(){
ActionContext context = ActionContext.getContext();
HttpParameters parameters = context.getParameters();
Parameter parameter = parameters.get("customer.name");
System.out.println(parameter);
}
2.当多个action的执行方法的validatexxx方法相同了,那么可以采用validate方法,Validate也是由DefaultWorkflowInterceptor类调用的,无需实现validatable接口因为这个actionsupport已经实现,使用时参数已经注入
28 自定义验证器
1)建立src下validators的2种方式
一种是通过com.opensymphony.xwork.validator.validatorfactory类的方法registervalidator,完成映射,键值对的方式
另一种是在src路径下添加一个名为validators.xml的文件
<validators>
<validator name="idcard" class="struts.IDCardValidator"/>
</validators>
常用的是第二种
2)拦截原理
开启验证是通过validation拦截来调用的,位于conversionerror之后,worflow之前
3)非字段验证器和字段验证器
非字段验证器不需要针对特定的验证规则,例如两次的密码是否一致
<validator type="expression">
<param name="expression"> <![CDATA[password==password2]]></param>
<message key="error"></message>
</validator>
对于字段类型的验证器,在声明时既可以用field声明也可以用validator声明
属性type表示验证器的名称,name验证得出字段名
<validators>
<field name="idcard">
<field-validator type="idcard">
<message key=“errorInfo”> </message>
</field-validator>
</field>
</validators>
备注:对于验证规则在相应的类的同一个包下,建立名称为classname-validator.xml或者classname-alias-validator.xml
4)自定义验证器需要继承FieldValidatorSupport类
重写validate方法
public void validate(Object arg0) throws ValidationException {
//获取属性名
String fieldName = getFieldName();
//获取属性值
Object value = this.getFieldValue(fieldName, arg0);
IDCard idCard = new IDCard();
if(!idCard.Verify((String)value)){
//错误信息加入错误字段
addFieldError(fieldName, arg0);
}
}
5)内置验证器
内置的13个验证器在com.opensymphony.xwork2.validator.validators下的default.xml中
用法见struts-2.5.14.1-all.zipstruts-2.5.14.1docsdocscore-developers其下的validation
6)自定义字段验证器需要的文件:src下的validators.xml,继承FieldValidatorSupport类的类,同验证类的包下的classname-validator.xml或者classname-alias-validator.xml文件,可选在i18n下写入错误消息,以及struts.xml中指定
7)自定义非字段验证器需要的文件如上,以及strus.xml中指定
29 自定义拦截器
1) AbstractInterceptor的继承,重写intercept方法
public String intercept(ActionInvocation arg0) throws Exception {
//调用下一个拦截器
String invoke = arg0.invoke();
return invoke;
}
2) struts.xml中添加
<interceptor name="testintercept" class="struts.myintercept"></interceptor>
3) 使用
一种是加入栈中,然后使用栈
一种是直接在action中使用
30. 避免表单的重复提交
1)原理
Token标签:其中有两个hidden 第一个是固定的,第二个是随机生成的加密令牌值,避免表单的重复提交需要添加tokeninterceptor或者tokensessionstoreinterceptor拦截器,需要手动添加,和web防止重复提交表单的原理相同,当重复提交是会转到invalid.token,当没有写相应的页面的时候那么不会转发到相应的页面,action不会运行
<interceptor-ref name="tokenSession"></interceptor-ref>
public static final String INVALID_TOKEN_CODE = "invalid.token";
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
2)什么算表单的重复提交
刷新不算重复提交 主要值返回后页面提交 提交的过程中再次点提交 按f5刷新 这些算表单的重复提交,转发算重复提交 重定向不算重复提交
3)Executeandwaitinterceptor
Executeandwaitinterceptor拦截器在用户提交表单后向用户输出一个等待的页面,等待页面定时向服务器提交请求,以确定服务器的操作是否完成,如果请求处理完毕,则会导向结果页面,当一个action的执行时间超过5或者10分钟时,他可以防止http请求超时
4)Execandwait
Execandwait拦截器在默认值的xml文件中有但是在默认的拦截器栈中没有添加,这个只能放在最后,否则会停止后续的操作,用于设置响应时间,threadpriority:可选参数,优先级
delay:可选 等待响应时间
delaysleepinterval:可选和delay只能用一个
31 文件的上传和下载
1) 上传下载的环境
需要导包fileupload和io包,对于文件的上传文件实行拦截的是org.Apache.struts2.interceptor.fileuploadinterceptor
上传文件的时候需要使用enctype属性,enctype=”multipart/from-data”
2) 上传拦截器提供的参数
Maximumsize:通知拦截器action可接收单个文件的长度 默认2m
Allowedtypes:以逗号隔开,表示文件的类型
相应的错误信息:struts.messages.error.uploading:文件不能上传的通用错误信息
Struts.messages.error.file.too.large上传的文件长度太大的错误信息
Struts.messages.error.content.type.not.allowed当上传文件不匹配指定的内容类型的错误信息
3)上传Struts2中有3个属性与文件有关,在struts.properties中,通过constant设置
Struts.multipart.parser 可选值pell cos Jakarta(默认)既使用asf的commons-fileupload
Struts.multipart.savedir 保存临时文件的存储路径 默认为 javax.servlet.context.tempdir
Struts.multipart.maxsize:最大字节数 默认为2097152
4)上传默认参数
List<String> nameContentType; 默认为name+ContentType
List<String> nameFileName; 默认为name+FileName
当多个文件时,上述变为数组,这些会通过自动注入的方式填充数据
<interceptors>
<!-- 添加拦截器名称和支撑类 声明 拦截器的意思 -->
<interceptor name="testintercept" class="struts.myintercept"></interceptor>
<interceptor-stack name="adsd">
<interceptor-ref name="defaultStack">
<!-- 查看的方式 是在拦截器指定的栈的类中的类可以查看doc文档里面有相应的介绍 -->
<!-- 单个文件的大小 字节为单位 -->
<param name="fileUpload.maximumSize">2000</param>
<!-- 允许文件的类型 -->
<param name="fileUpload.allowedTypes">text/html</param>
<!-- 允许文件的拓展名 -->
<param name="fileUpload.allowedExtensions">.dtd,.xml,.txt</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
5)下载
需要继承actionsupport
Strust2.dispatcher.streamresult类型支持文件的下载
Streamresul结果类型利用httpservletresponse对象返回的servletoutputstream向对象输出下载文件的二进制数据,他的参数如下
contentLength: 下载的文件的长度
contentDisposition: 设定
Content-Dispositoin 响应头. 该响应头指定接应是一个文件下载类型, 一般取值为 attachment;filename="document.pdf".,filename指定文件的下载名,inline表示下载文件在本页面内部打开
inputName: 指定文件输入流的 getter 定义的那个属性的名字. 默认为 inputStream
bufferSize: 缓存的大小. 默认为 1024
allowCaching: 是否允许使用缓存
contentCharSet: 指定下载的字符集
private String contentType;
private long contentLength;
private String contentDisposition;
private InputStream inputStream;
public String execute() throws Exception {
contentType="text/html";
contentDisposition="attachment;filename=i18n.properties";
ServletContext context=ServletActionContext.getServletContext();
String fileName=context.getRealPath("/i18n.properties");
inputStream=new FileInputStream(fileName);
contentLength=inputStream.available();
return SUCCESS;
}
<!—type需改为stream-->
<result type="stream">
<param name="bufferSize">2048</param>
</result>
32. 实现modledriven接口
Getmodle方法在action的execute方法之前执行
modledriven对象里面的对象具有的名称会被优先注入
这个方法是在validatexxx后续执行
因为只依赖注入一次
假如想前面的也依赖注入那么需要使用paramsPrepareParamsStack拦截器
33. Preparable
用法与validatexxx类似,preparexxx主要为调用数据库做准备,相应的方法运行时采用调用,实现Preparable也会需要实现prepare方法,所以这个方法,而validatexxx不需要实现接口,由dointercept调用,不想执行和继承prepare方法,可以添加参数如下
<interceptor-ref name="paramsPrepareParamsStack">
<!-- 修改方法值 将prepare.alwaysInvokePrepare改为false那么就不会再执行prepare方法-->
<param name="prepare.alwaysInvokePrepare">false</param>
</interceptor-ref>
在使用默认的拦截器栈时,参数没有注入,在使用paramsPrepareParamsStack参数已经注入,详细看
34. ognl
ognl表达式的三要素及参数的出处
表达式 root对象 上下文环境
Ognl的运行参数都属于struts2/xwork需要定义的内置变量,
Ognl
ognl支持的常量
字符串常量,需要用单引号, 数值常量 布尔常量 null常量
操作符
,分隔表达式
{} 用于创建集合列表
In not in 是否包含在集合中
方法和属性的调用
调用普通方法
可以访问值栈中对象的方法,相应获取返回值
调用静态方法和静态属性
使用注解的方式 @[email protected] @[email protected] 如果省略class默认为java.lang.math
需要设置<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>可是非值栈中的属性
调用构造方法
New 全类名 例如new java.util.ArrayList()
索引的访问
数组和list访问 array【index】 list【index】
创建集和数组
创建列表 {“a”,“b”…….}
创建map集合#{“A:a”,“B:b”………}
创建数组同java
说明:这些集合不能调用java中的方法,因为这些不符合访问器方法的命名要求,在不涉及这些参数的方法都能用
List能用的方法:size isempty iterator
Set 能用的方法: size isempty iterator
Map 能用的方法:size isempty keys values
Iterator 能用的方法 next hasnext
Enumeration 能用的方法 next hasnext nextelement hasmoreelement
投影
在一个集合中对每一个元素调用相同的方法,或者抽取相同的属性,将结果保存为一张新的表
语法: 集合.{相应的表达式} 使用例如:#employees.{? name==null}
相应表达式中3个特殊的符号
? 取出所有符合逻辑的元素
^ 取出符合逻辑的第一个元素
$ 取出符合逻辑的最后一个元素
Struts在ognl上的增强
获取对象栈的值:语法 【n】.xxxx 栈顶【0】.默认可以不写 例如【1】.name
Top关键字:top关键字相当于栈顶对象 例如value=“top”等于获取栈顶对象
访问静态变量的增强:访问值栈中对象的静态变量和静态方法可以用vs前缀代表类名,vs1表示值栈中对应位置的类 vs表示栈顶 语法@[email protected]字段名或者方法名
获取保存在actioncontext中的map类型的值需要使用#,包含parameters,request,session,application,attr 用法例如value=”#attr.name”
说明在jsp2.1中使用#可能会出现问题,对此一种修复的方式是在web.xml中添加jsp-config元素配置,忽略在jsp中使用el表达式
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</ url-pattern >
<el-ignored>true</ el-ignored >
</jsp-config>
Struts2标签语法
动态数据的访问
对于字符串类型的属性,假如需要动态的访问数据,需要使用%{},例如<s:include value=“%{url}”>
对于非字符串类型的ognl属性可以直接求值
直接指定字符串通常需要单引号括起来,如果是非字符串属性那么%{}会被忽略,
通用标签
数据标签
Property set push param bean action include url a i18n text date debug
property:输出某个属性
default:可选 如果输出属性值为空 则显示defalut属性指定的值
escape:可选 默认值为true
value: 可选 指向输出的属性值,没有则输出栈顶的值
Set:设置一个新的变量,放入指定的范围内
Scope:可选 范围 application session request page action 默认值action
Value:可选 默认栈顶对象
name:必选,指定该属性后会被放入值栈中
Push:用于将某个值放入值栈中
Value:必选 指定需要放入值栈栈顶的值
Param:用于设置一个参数,通常是用做bean标签,url标签的子标签
Name:可选,指定需要设置的参数名
Value:可选;指定需要设置的参数值
两种写法
<param name=”qqq”>aaa</param>
<param name=”qqq” value=”aaa”/>
Bean:该标签用于创建一个javabean实例
属性
Name:必选 需要实例化的类
id:可选 指定用于引入值栈
Action:在jsp页面直接调用一个action,通过指定的executeresult参数还可以将该action的处理结果包含到本页面中来
属性:
id:可选,引用的名称
Name:必选,用于指向action的name,也就是调用action
Namespace:可选,指定标签所在的namespace
Executeresult:可选,是否将action处理结果包含到本页面,默认值为false
Ignorecontextparams:可选,指定该页面中的请求参数是否需要传入调用的action,默认值为false,即不会将本页面的参数传入
Flush 可选 默认值true 在action标签结束时,输出结果是否应该被刷新
Include:用于页面包含jsp或者servlet资源
Value 必选,该属性指定被包含的jsp页面或者servlet
在其中还可以使用param子标签来传递参数
url:用于生成一个url地址
action:可选 指定url的地址为那个action,如果没有指定value作为url
achor:可选 锚点
encode:可选 是否需要对参数进行编码 默认为true
Param:用于设置一个参数,通常是用做bean标签,url标签的子标签
Name:可选,指定需要设置的参数名
Value:可选;指定需要设置的参数值
两种写法
<param name=”qqq”>aaa</param>
<param name=”qqq” value=”aaa”/>
Push:用于将某个值放入值栈中
Value:必选属性 指定需要放入值栈栈顶的值
escapeamp:可选是否需要对&符号进行编码 默认为true
forceaddschemehostandport:可选 指定是否再url对应的地址里强制添加scheme,主机和端口
includecontext:可选,是否需要当前上下文包含在url地址中
includeparams:可选 指定是否包含请求产生,只有none,get或者all,默认为get
method:可选 指定action的方法 如果指定了该属性,则url连接到指定action的相应方法
portetmode:可选,指定结果页面的protlet模式
namespace:可选,如果指定,那么url将连接到此namespace的指定action处
scheme:可选,用于设置scheme属性
value:如果不提供action就是url地址
var:放入值栈中保存
windowstate:可选,指定portlet的窗口状态
上述如果没有指定value和action那么该页面作为url的地址的值
I18n:用于指定国家化资源文件的basename
Date:用于格式化输出一个日期
Format:可选属性,解析格式
Nice:可选属性 指定是否输出指定日期与当前的时间差 默认值为false
Name:必选属性,指定要格式化的日期
Var:指定是否放入值栈的栈顶 也可以用id,但是建议使用var
其中nice和format不能同时指定 如果没有指定nice和format则会寻找key为struts.date.format的消息,如果没有就输出dateformat.medium的消息
Debug:生成一个调试连接可以看到值栈的内容
控制标签
If/elseif/else iterator append merge generator subset sort
If:选择 test 必选 Boolean
Elseif test 必选 Boolean
Else
Iterator:迭代器
Value:可选属性,value属性指定的被迭代的集合,如果没有value属性,这迭代栈顶元素
Id:可选属性 指定集合里元素的id,例如后续的输出就需要指定这个值,相应的输出
Status:可选属性 判断当前迭代元素的信息,例如是否是最后一个元素,
Status包含以下方法
Int getcount():返回当前迭代的第几个元素
Int getindex(): 返回当前迭代元素的索引
Boolean iseven():返回当前被迭代元素的索引是否是偶数
Boolean isfrist():返回当前被迭代元素是否是第一个元素
Boolean islast():返回当前被迭代元素是否是最后一个元素
Boolean isodd():返回当前被迭代元素的索引是否是奇数
Append:将多个集合合成一个新的集合
Id 必选 该属性确定拼接成的新的集合的名字,append标签中可以放置多个param标签使得合成一个和解
Merge:也是将多个集合合成一个集合,但是于append的拼接方式有所不同
这个拼接的顺序与append不同,append是第一个集合的第一个元素到最后一个元素,再到第二个元素,以此类推,而merge是第一个集合的第一个元素,然后是第二个集合的第一个元素,到最后一个集合的第一个元素,然后是第一个元素的第二个元素,依次类推
使用与append的大致相同
Generator:将一个字符串解析成一个集合
可以将字符串按指定分割符分割成多个子串,然后转化为一个集合,这个临时生成的集合位于栈顶,标签结束移出栈顶
Count:该属性是一个可选值,指定生成集合中元素的总数
Separate:必选属性,指定分隔符
Val:必选属性,指向解析的字符串
Converter:可选属性,一个转换器,将集合中的每一个元素转换成对象,该属性值必须是一个相应的converter对象
id:可选属性:如果指定该属性,则生成的迭代对象会放入值栈中
Subset:截取结合的部分元素形成新的集合
Count:可选属性,指定元素的格式,不指定,则是全部元素
Source:可选属性,指定需要被截取的集合,不指定,默认为栈顶的集合
Start:可选属性,指定从第几个元素开始
Decider:可选属性,
id:可选属性,指定该属性,则生成迭代对象设置为page范围
Sort:对集合进行排序
Comparator:必选属性,指定需要进行排序的comparator实例
Source:可选属性,指定需要排序的集合,没有指定默认为栈顶集合
id:可选属性,指定后迭代对象设置为page范围
ui标签
struts2支持的模板
模板:ftl文件是freemarker模板文件,struts2使用freemarker技术来定义所以模板文件
Flt:默认模板,freemarker的模板技术
Vm:基于velocity的模板技术
Jsp:基于jsp的模板技术
加载模板的方式 在struts.properties文件中的struts.ui.templatedir属性来配置,该属性的默认值是theme ,加载模板时首先搜索web应用程序下的template目录,然后搜索classpath下的template目录,可以通过ui标签的templatedir指定模板路径
例如:<s:form action="input.action" theme="模板主题" templateDir="path">
模板的主题:
Simple xhtml css_xhtml ajax
Xhtml:是struts2默认的主体,是对simple主体的拓展
1) 会进行客户端验证
2) 自动输出验证错误
css_xhtml 与上类似
ajax主题是对xhtml的拓展,增加ajax特性,使用流行的dojo工具包
1) 客户端验证
2) 支持远程异步提交
3) 高级div模块
4) 交互的autocomplete等
常用表单标签
Form textfield password radio checkbox checkboxlist select
Doubleselect combobox optiontransferselect optgroup updownselect
Textarea hidden file label reset submit token head
下面类似html中常用的标签属性有省略
Form:
Enctype 可选 上传文件是需要指定为multipart/form-data
Validate 可选 默认值false 是否执行客户端验证 只有xthml或者ajax才有效
Textfiled
Maxlength:可选 可输入文本的最大长度
Readonly 不能输入文本只能读
Size 可选 设置可以看见的尺寸
Textarea
Wrap:可选指定文本输入框是否可以换行
Select标签 下拉框
List:指定集合,可以是list集合
Listkey:指定集合元素中的对象的某个属性作为键
Listvalue:指定集合元素中的对象的某个属性作为值
Multiple:是否允许多选
Headerkey headervalue 类似listkey和listvalue ,不同在于这个现实在第一行,默认可见行
Checkboxlist复选框
略
Doubleselect级联列表框
List:指定集合
Listkey:
Listvalue
Doublelist:第二个集合
Doublelistkey:
Doublelistvalue
Doublename’:第二的name属性
Radio标签 单选按钮
略
Optgroup标签 在select下的标签
List:指定集合 ,需要是键值对
Listkey:
Listvalue
Token标签 防止重复提交 原理用了一个隐藏值,也类似web防止表单的重复提交
Submit 标签
Type 可选 默认input 可以是input button image
Input 等价于<input type=“submit”>
Image 等价于<input type=“image”>
Button 等价于<button type=“submit”>
Method 可选 指定action方法
Method前缀:可以改变默认的execute方法的执行
<s:submit value=”注册“ name=”method:login”>
Action前缀 导向到另外一个action处理 类似chain
<s:submit value=”注册“ name=”action:login”>
Redirect前缀 重定向到其他url
<s:submit value=”注册“ name=”redirectn:path”>
Redirect-action前缀:重定向到其他的action
等等 其余基本类似
Actionerror actionmassage fielderror标签
Actionerror:action的错误消息 Actionerrors属性保存的的
Actionmassage:一般性消息 Actionmassages属性保存
Fielderror错误消息 Fielderrors属性保存的
3个输出都依赖主体
备注:
Constant常用的配置
struts.local 指定web应用的默认的locale 默认的locale为en_US
struts.configuration 该常量指定加载struts配置文件的配置管理器 默认为org.apache.struts2.config.DefaultConfiguration 也可以指定 但是需要实现configuration类
struts.ObjectFactory :指定struts2默认的ObjectFactory bean
struts.ObjectFactory.autoWare:指定spring框架的自动装配模式,默认值为name (即根据bean的name自动装配)
struts.enable.dynamicMethodInvocation:该常量设置struts2是否支持动态方法调用,默认值为false
struts.devMode 该常量设置struts2应用使用开发模式 默认值为false
struts. Enable.SlasheslnActionNames:该常量设置struts是否有允许在action名中使用/ 默认值为false
struts.reload 该常量设置是否每次http请求到达时,系统都重新加载资源文件,默认值为false,但是通常在开发阶段设置为true,在发布阶段设置为false
struts.ognl.allowStaticMethodAccess:该常量设置是否允许在ognl表达式中调用静态方法,默认为false
struts.mutipart.maxsize 该常量指定struts2文件上传中整个请求内容允许的最大字节数
struts.action.extension: 指定struts2处理的请求后缀,该常量的默认值为action,需要别的类型的后缀则需要相应的添加
struts.i18n.encodin:指定web应用的默认编码集 默认值为utf-8
struts.custom.i18n.resources:该常量指定struts2应用所需要的国际资源问价
等等 详情见路径下的默认配置
使用方式如下
<constant name="struts.action.extension" value="action,do"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="i18n"></constant>
其它类似如上
default-interceptor-ref说明
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/> 将异常和action返回的result相应射
<interceptor-ref name="alias"/> 对http包含的参数设置别名
<interceptor-ref name="servletConfig"/> 该拦截器提供访问包含HttpServletResquest和HttpServletResponse对象的Map的方法。
<interceptor-ref name="i18n"/> 支持国际化的拦截器
<interceptor-ref name="prepare"/> 假如action继承了preparable接口会调用prepare方法(prepare方法可以为action的execute做相应的准备工作)
<interceptor-ref name="chain"/> 该拦截器让前一个action的参数可以在现有action中使用
<interceptor-ref name="scopedModelDriven"/> 执行该拦截器时 它可以从一个scope范围检索和存储model值 通过调用setmodek方法区设置model值
<interceptor-ref name="modelDriven"/> action执行该拦截器时 可以将getmodel方法得到的result值放入值栈中
<interceptor-ref name="fileUpload"/> 支持文件上传功能的拦截器
<interceptor-ref name="checkbox"/>视图中如果有checkbox存在的情况,该拦截器自动将unchecked的checkbox当作一个参数(通常值为“false”)记录下来。 这样可以用一个隐藏的表单值来记录所有未提交的checkbox,而且缺省unchecked的checkbox值是布尔类型的, 如果视图中checkbox的值设置的不是布尔类型,它就会被覆盖成布尔类型的值。
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>多选拦截器,如果找到带有多选前缀的参数,则会相应的插入一个值,如果不存在的话那么插入默认值(空字符串数组)
<interceptor-ref name="staticParams"/>对于在struts.xml文件中Action中设置的参数设置到对应的Action中
<interceptor-ref name="actionMappingParams"/>使用ActionMapping使其映射到值栈上
<interceptor-ref name="params"/>将http请求中包含的参数设置到action中
<interceptor-ref name="conversionError"/> 从actioncontext中转化类型是发生的错误添加到action值域错误中
<interceptor-ref name="validation">定义的校验规则
<param name="excludeMethods"> input, back, cancel, browse </param>
</interceptor-ref>
<interceptor-ref name="workflow">调用Action的validate方法,一旦有错误返回,重新定位到INPUT
<param name="excludeMethods"> input,back ,cancel, browse </param>
</interceptor-ref>
<interceptor-ref name="debugging"/>用来对在视图间传递的数据进行调试
</interceptor-stack>
Result类型结果说明
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> 转发到一个action而不是页面(从一个action处理完后转发到另外一个action)
<result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/> 转发到一个页面
当一个请求到来,服务器直接转发到另一个页面,不能是另一个action。由于这个过程在服务器内部完成,客户端(浏览器)并不知道,所以在地址栏不会显示真实访问的页面,而显示都是所请求的action的地址。在servlet中相当与forword转发。
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> 使用freemark模板
<result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/> 用于控制特殊的http行为
<result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/> 重定向到一个页面
当一个请求到来,服务端将实际地址response给浏览器,然后浏览器重新发起请求,这个过程,浏览器是知道访问的页面的实际地址的,所以在浏览器的地址栏显示的是实际访问的jsp页面地址。但是这种类型不能重定向到一个action.
<result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/> 重定向到一个action而不是页面(从一个action处理完后重定向到另外一个action)
<result-type name="stream" class="org.apache.struts2.result.StreamResult"/>向浏览器换回一个inputstream
<result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/> 使用velocity模板
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> 用于xml/xslt整合
<result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" /> 显示某个页面的源代码
<result-type name="postback" class="org.apache.struts2.result.PostbackResult" />
以上是关于sshstruts2的主要内容,如果未能解决你的问题,请参考以下文章