超全面 struts2 复习总结笔记
2018-02-06 21:34
344 查看
如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/64934709
What ? 最近怎么开始写后端的博客了?
从去年开始就经常看到别人提“移动开发寒冬”,而年初投简历的时候更是亲身体会,不写3年经验连面试机会都没有,那么没有经验或经验少的人能怎么办呢,从一开就找不到工作怎么可能会有经验?
然而绝望并没有用,我算运气好,勉强找到一份工作。
从趋势来看,近几年移动开发待遇不会很好,今年发现到处缺后端,于是决定还是搞后端吧,因为搞安卓不过一年,后端的知识还没忘完(好吧,实际上以前后端也没多深入),于是利用下班时间复习后端(好吧,其实好多是预习了●﹏●),并把知识整理出来分享给大家。
环境搭建
Action
配置详解
通配符和动态方法调用
OGNL
Struts 标签
Validator
Interceptor
国际化
常见例子
直接下载导入
http://struts.apache.org/download.cgi
可根据需要选择 all min src 等包,如果仅仅是学习,选择 min 包就够了
版本管理工具导入
Gradle
Maven
上面的仅仅是核心包,根据需要可引入其他包,比如注解包
[/code]
struts2 基于拦截器,因此,配置的第一步是在 WEB-INF/web.xml 中配置 struts2 拦截器。
配置的时候需要注意,不同的版本的
* 2.5.x 版本
2
3
4
5
6
7
8
9
10
11
[/code]
为了防止篇幅过大,其他版本就不写了。
在 src 目录下建立 struts.xml,Idea 中需要放到 resources 下。
2
3
4
5
6
7
[/code]
编写一个类继承 ActionSupport, 并提供一个无参返回字符串且公开的方法,如下:
2
3
4
5
6
[/code]
类似于 Servlet,struts2 使用 action 来处理请求。
使用 action 需要进行配置。
xml 配置
在 struts.xml 的 struts 标签里面配置 action
如下:
2
3
4
5
[/code]
action 外面是 package,类似于 java 的包。
这里简单介绍 action 的属性,后面配置详解里会一一介绍大部分标签和属性。
name: 访问 action 的名称,如果没有配置 namespace,则 根路径/name 就是 action 的访问地址。
class 和 method 则是指定 action 的类和方法。
注解配置
使用注解前必须保证 已经导入了 struts2-convention-plugin 的包。
在 Action 类上加上
在对应的方法上加上
2
[/code]
如下:
2
3
4
5
6
7
8
9
[/code]
配置好后,就可以通过浏览器访问(根路径取决于项目配置)
http://127.0.0.1/strut2/hello.action
如果访问成功,控制台后打印
登录是很常见的 action,这个时候一般要向服务器传递 username, password 等。
创建一个 User 实体对象,假设里面只有 username, password。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
创建一个 UserAction 来处理请求,简单起见,使用注解方式配置。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
实现 ModelDriven 方法,返回 user。
然后在执行 login 方法之前,ModelDriven 拦截器会给 user 设置请求提交的值。
使用 ServletActionContext
比如:
2
[/code]
用于引入其他 struts2 配置文件
比如:
2
3
4
[/code]
是 的一个子元素,用于指定 action 的结果视图。
type 类型
包内全局的结果视图,包内 action 没有配置 result 时,会使用全局结果视图。一般是在基础包里面配置,比如全局的登录验证。
用于声明拦截器。
在 interceptors 中配置 interceptor, interceptor-stack,interceptor-ref 等声明拦截器。
用于配置包的默认拦截器。
用于配置 struts2 中的常量。
struts2 中 action 的 name 支持通配符
用于匹配0个或多个字符。
旧版中可以直接使用,在新版中,需要启用通配符。
在 package 开头加上
2
[/code]
此外还可以通过 {n} 来引用 匹配的值。
2
3
[/code]
如上配置,我们访问
struts2 支持动态指定 action所绑定的方法名,也就是不需要配置 action 的 method。
在请求中使用
比如:
[/code]
默认是关闭的,要使用需要配置。在 struts 标签下加上:
[/code]
OGNL 是 Object Graph Navigation Language (对象图形导航语言)的缩写。
主要用来访问 栈 和 map 中的对象。
支持对象方法调用,如 xxx.doSomeSpecial();
支持类静态的方法调用和值访问,表达式的格式:
@[类全名]@[方法名 | 值名],例如:
但需要设置 struts.ognl.allowStaticMethodAccess=true
支持赋值操作和表达式串联,如 price=100, discount=0.8,
price*discount,这个表达式会返回80;
访问OGNL上下文(OGNL context)和ActionContext;
操作集合对象。
在 jsp 中使用 OGNL 需要引入 struts tag lib。
[/code]
然后使用 标签 s:property:
[/code]
使用引号引起来表示字符串,否则就是 OGNL 表达式
ValueStack 实际是一个接口,在 Struts2 中利用OGNL时,实际上使用的是该接口实现类 OgnlValueStack。
每个 Action 类的对象实例都有一个 ValueStack 对象,用于保存参数或结果。
在 ValueStack 对象的内部有两个逻辑部分:
* ObjectStack: Struts 把动作和相关对象压入 ObjectStack 中,看作 List 容器。
* ContextMap: Struts 把各种各样的映射关系存入 ContextMap 中,看作 Map 容器。
Struts2 会把下面这些对象存入 ContextMap 中
* parameters: 该 Map 中包含当前请求的请求参数
* request: 该 Map 中包含当前 request 对象中的所有属性
* session: 该 Map 中包含当前 session 对象中的所有属性
* application:该 Map 中包含当前 application 对象中的所有属性
* attr: 该 Map 按如下顺序来检索某个属性: request, session, application
ObjectStack: 直接通过元素的名称进行访问。
ContextMap: 需要在开头加一个
比如 ObjectStack 和 ContextMap 中都存放了一个 User,而 User
有属性 username,那么我们可以通过如下代码进行访问:
jsp 中:
2
3
4
5
6
7
8
9
10
[/code]
Action 中:
2
3
4
5
6
7
8
[/code]
#
1、取 contextMap 中 key 时使用,例如
2、OGNL 中创建Map对象时使用,例如:
$
1、在JSP中使用EL表达式时使用,例如
2、在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。
%
在struts2中,有些标签的value属性取值就是一个OGNL表达式,例如
还有一部分标签,value属性的取值就是普通字 符串,例如
例如
“?#”:过滤所有符合条件的集合,如:users.{?#this.age > 19};
“^#”:过滤第一个符合条件的元素,如:users.{^#this.age > 19};
“#”:过滤最后一个符合条件的元素,如:users.{#this.age
> 19}
常见的表单标签在 struts2 中都有
比如: form,textfield,password,checkbox,checkboxlist ,hidden,submit,reset 等。
2
3
4
5
6
7
8
9
10
11
12
[/code]
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
2
3
4
5
6
[/code]
2
3
4
5
[/code]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[/code]
struts2为我们共内置了16个验证器,且全部是基于字段的验证器。
验证字段的值是不是 null。注意,不是空字符串或空白字符串。
2
3
4
5
6
7
[/code]
验证字段的值既不是null、也不是空白。
参数:
* fieldName:要验证的字段名
* trim:是否去掉首尾空格
2
3
4
5
6
7
8
9
10
11
12
13
[/code]
验证某个字段的值是否可以被转换为一个整数。还可以验证是否在允许的范围内。
参数:
* fieldName:要验证的字段名
* min:允许的最小值
* max:允许的最大值
基于字段的验证
2
3
4
5
6
7
8
9
[/code]
基于验证器的验证
2
3
4
5
6
7
8
[/code]
同 int
用来验证某个字段的值是否可以被转换为一个双精度浮点数。还可验证是否在允许的范围内。
参数:
* fieldName:要验证的字段名
* minInclusive:允许的最小值,包含最小值
* maxInclusive:允许的最大值,包含最大值
* minExclusive:允许的最小值,不包含最小值
* maxExclusive:允许的最大值,不包含最大值
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
用来确保给定的日期字段的值在指定的范围内。
参数:
* fieldName:要验证的字段名
* min:允许的最小值,包含最小值
* max:允许的最大值,包含最大值
2
3
4
5
6
7
8
9
[/code]
用于验证是否满足一个OGNL表达式。这是一个非字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个动作错误,因此要显示该错误,需要使用标签。
2
3
4
5
6
7
8
[/code]
用于验证某个字段是否满足一个OGNL表达式。这是一个基于字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个字段错误。
参数:
* fieldName:要验证的字段名
* expression:OGNL表达式,只有该表达式为true才能验证通过
2
3
4
5
6
7
8
9
10
[/code]
用来验证给定的字段是否符合一个Email的规范。它的正则表达式为
[/code]
2
3
4
5
6
7
[/code]
用来验证给定的字段值是否是一个合法的URL地址。
2
3
4
5
6
7
[/code]
该验证程序可以提高代码的可重用性,你可以利用它把同一个验证程序配置文件用于多个动作。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
用来验证一个非空的字段值是不是有足够的长度。
用来检查给定字段是否与给定的正则表达式相匹配。正则表达式的详细内容可以参考 JDK 的
参数:
* fieldname:要验证的字段名
* expression:正则表达式
* caseSensitive:是否区分大小写的情况,默认 true
* trim:是否去掉首尾空格,默认 true
2
3
4
5
6
7
8
[/code]
Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截, Struts2 拦截器是可插拔的, 拦截器是 AOP 的一种实现.
conversionError:将错误从ActionContext中添加到Action的属性字段中。
fileUpload:提供文件上传功能
i18n:记录用户选择的locale
model-driven:如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。
params:将请求中的参数设置到Action中去。
servletConfig:提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。
token:避免重复提交
validation:使用 action-validation.xml 文件中定义的内容校验提交的数据。
workflow:调用 Action 的 validate 方法,一旦有错误返回,重新定位到 INPUT 视图
自定义拦截器
在 struts.xml 文件中配置自定义的拦截器
struts2 中使用的 properties 文件来做国际化
全局资源包
2
3
4
[/code]
包范围的资源包:把 资源包放在某包下面,命名为:
局部消息资源包:把 资源包放在某动作类路径下,命名为:
资源包的使用顺序:局部 > 包范围 > 全局
Action
jsp
当注定的包下没有找到指定的值时,会按顺序搜索配置了的资源包
2
3
[/code]
使用重定向,避免刷新就提交
使用 tokensession 或 token 拦截器
表单中加入
2
3
[/code]
配置中加入 tokensession 拦截器
2
3
4
5
[/code]
token 和 tokensession 功能一样,但有一些差别。
token 拦截到重复提交后,会转向
而 tokensession 拦截之后不转向任何视图
html
2
3
4
5
[/code]
action
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[/code]
修改上传文件大小限制
2
[/code]
限制上传文件扩展名
2
3
4
5
6
[/code]
多文件上传需要把
2
3
[/code]
改成,也就是改成数组
2
3
[/code]
action
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
配置
转载至 http://blog.csdn.net/qq_35064774/article/details/64934709
前言
What ? 最近怎么开始写后端的博客了?从去年开始就经常看到别人提“移动开发寒冬”,而年初投简历的时候更是亲身体会,不写3年经验连面试机会都没有,那么没有经验或经验少的人能怎么办呢,从一开就找不到工作怎么可能会有经验?
然而绝望并没有用,我算运气好,勉强找到一份工作。
从趋势来看,近几年移动开发待遇不会很好,今年发现到处缺后端,于是决定还是搞后端吧,因为搞安卓不过一年,后端的知识还没忘完(好吧,实际上以前后端也没多深入),于是利用下班时间复习后端(好吧,其实好多是预习了●﹏●),并把知识整理出来分享给大家。
目录
环境搭建Action
配置详解
通配符和动态方法调用
OGNL
Struts 标签
Validator
Interceptor
国际化
常见例子
1.环境搭建
导包
直接下载导入http://struts.apache.org/download.cgi
可根据需要选择 all min src 等包,如果仅仅是学习,选择 min 包就够了
版本管理工具导入
Gradle
compile "org.apache.struts:struts2-core:2.5.10.1"
Maven
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.10.1</version> </dependency>
上面的仅仅是核心包,根据需要可引入其他包,比如注解包
compile "org.apache.struts:struts2-convention-plugin:2.5.10"1
[/code]
配置
web.xml
struts2 基于拦截器,因此,配置的第一步是在 WEB-INF/web.xml 中配置 struts2 拦截器。配置的时候需要注意,不同的版本的
StrutsPrepareAndExecuteFilter包路径不一样,配置的时候,可以用 IED 搜索这个类,复制路径。比如 Idea 的搜索类快捷键是
Ctrl + N。
* 2.5.x 版本
``` <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ```1
2
3
4
5
6
7
8
9
10
11
[/code]
为了防止篇幅过大,其他版本就不写了。
struts.xml
在 src 目录下建立 struts.xml,Idea 中需要放到 resources 下。<?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> </struts>1
2
3
4
5
6
7
[/code]
2.Action
HelloAction
类
编写一个类继承 ActionSupport, 并提供一个无参返回字符串且公开的方法,如下:public class HelloAction extends ActionSupport { public String hello() throws Exception { System.out.println("hello world!"); return SUCCESS; } }1
2
3
4
5
6
[/code]
配置 Action
类似于 Servlet,struts2 使用 action 来处理请求。使用 action 需要进行配置。
xml 配置
在 struts.xml 的 struts 标签里面配置 action
如下:
<package name="p1" extends="struts-default"> <action name="hello" class="com.ittianyu.web.action.HelloAction" method="login"> <result name="success">hello.jsp</result> </action> </package>1
2
3
4
5
[/code]
action 外面是 package,类似于 java 的包。
这里简单介绍 action 的属性,后面配置详解里会一一介绍大部分标签和属性。
name: 访问 action 的名称,如果没有配置 namespace,则 根路径/name 就是 action 的访问地址。
class 和 method 则是指定 action 的类和方法。
注解配置
使用注解前必须保证 已经导入了 struts2-convention-plugin 的包。
在 Action 类上加上
@ParentPackage("struts-default")
在对应的方法上加上
@Action(value = "hello", results = { @Result(name = "success", location="/hello.jsp")})1
2
[/code]
如下:
@ParentPackage("struts-default")1
public class HelloAction extends ActionSupport {
@Action(value = "hello", results = { @Result(name = "success", location="/hello.jsp")})
public String hello() throws Exception {
System.out.println("hello world!");
return SUCCESS;
}
}
2
3
4
5
6
7
8
9
[/code]
配置好后,就可以通过浏览器访问(根路径取决于项目配置)
http://127.0.0.1/strut2/hello.action
如果访问成功,控制台后打印
hello world!。
向 Action 传递参数
登录是很常见的 action,这个时候一般要向服务器传递 username, password 等。
User
创建一个 User 实体对象,假设里面只有 username, password。public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
UserAction
创建一个 UserAction 来处理请求,简单起见,使用注解方式配置。@ParentPackage("struts-default") public class UserAction extends ActionSupport implements ModelDriven<User>{ private User user = new User(); @Action(value = "login", results = { @Result(name = "success", location="/home.jsp")}) public String login() throws Exception { System.out.println(user.getUsername()); System.out.println(user.getPassword()); return SUCCESS; } @Override public User getModel() { return user; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
实现 ModelDriven 方法,返回 user。
然后在执行 login 方法之前,ModelDriven 拦截器会给 user 设置请求提交的值。
获取 Servlet Api
使用 ServletActionContext比如:
ServletActionContext.getRequest(); ServletActionContext.getResponse();1
2
[/code]
3.配置详解
include
用于引入其他 struts2 配置文件比如:
<struts> <include file="struts-part1.xml"/> <include file="struts-part2.xml"/> </struts>1
2
3
4
[/code]
package
名称 | 类型 | 默认 | 必须 | 描述 |
---|---|---|---|---|
name | string | 无 | yes | 包的名称 |
extends | string | 无 | no | 这个包所继承的父包名称.一般继承 struts-default |
namespace | string | / | no | 包的命名空间,如果配置了,在访问时要加上包名 |
abstract | boolean | false | no | 是否是抽象包,如果是,专门设计来被继承,一般配置了自己的拦截器栈时,会设计基础包。 |
action
名称 | 类型 | 默认 | 必须 | 描述 |
---|---|---|---|---|
name | string | 无 | yes | 动作的名称 |
class | string | com.opensymphony.xwork2.ActionSupport | no | 绑定的动作类。若不配置,则为默认返回 success 的动作类。 |
method | string | execute | no | 动作绑定的方法 |
converter | string | 无 | no | 动作的类型转换器 |
result
是 的一个子元素,用于指定 action 的结果视图。名称 | 类型 | 默认 | 必须 | 描述 |
---|---|---|---|---|
name | string | success | no | 对应动作方法的返回值 |
type | string | dispatcher | no | 结果类型。struts定义的结果类型有10种。 |
序号 | 结果类型 | 取值 | 描述 |
---|---|---|---|
1 | Chain Result | chain | 转发方式转到一个antion |
2 | Dispatcher Result | dispatcher | 转发到一个页面 |
3 | FreeMarker Result | freemarker | |
4 | HttpHeader Result | httpheader | |
5 | Redirect Result | redirect | 重定向到一个页面 |
6 | Redirect Action Result | redirectAction | 重定向转到一个action |
7 | Stream Result | stream | 输出流,一般用于下载 |
8 | Velocity Result | velocity | |
9 | XSL Result | xslt | |
10 | PlainText Result | plainText | 常用于显示个别页面的源码 |
global-results
包内全局的结果视图,包内 action 没有配置 result 时,会使用全局结果视图。一般是在基础包里面配置,比如全局的登录验证。
interceptors
用于声明拦截器。在 interceptors 中配置 interceptor, interceptor-stack,interceptor-ref 等声明拦截器。
default-interceptor-ref
用于配置包的默认拦截器。
constant
用于配置 struts2 中的常量。
4.通配符和动态方法调用
通配符
struts2 中 action 的 name 支持通配符 *。
用于匹配0个或多个字符。
旧版中可以直接使用,在新版中,需要启用通配符。
在 package 开头加上
<!--动态方法配置,2.5之后额外配置允许的方法名--> <global-allowed-methods>regex:.*</global-allowed-methods>1
2
[/code]
此外还可以通过 {n} 来引用 匹配的值。
<action name="*_*" class="com.ittianyu.javaeetest.web.action.{2}Action" method="{1}{2}"> <result name="success">/{1}{2}.jsp</result> </action>1
2
3
[/code]
如上配置,我们访问
hello_World时,会自动匹配方法 helloWorld,并在方法执行完成后,转发到 helloWorld.jsp
动态方法调用
struts2 支持动态指定 action所绑定的方法名,也就是不需要配置 action 的 method。在请求中使用
!分割,后面写调用的方法名。
比如:
http://127.0.0.1/struts2/user!add1
[/code]
默认是关闭的,要使用需要配置。在 struts 标签下加上:
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>1
[/code]
5.OGNL
OGNL 是 Object Graph Navigation Language (对象图形导航语言)的缩写。主要用来访问 栈 和 map 中的对象。
支持对象方法调用,如 xxx.doSomeSpecial();
支持类静态的方法调用和值访问,表达式的格式:
@[类全名]@[方法名 | 值名],例如:
@java.lang.String@format('foo %s', 'bar') 或 @tutorial.MyConstant@APP_NAME;
但需要设置 struts.ognl.allowStaticMethodAccess=true
支持赋值操作和表达式串联,如 price=100, discount=0.8,
price*discount,这个表达式会返回80;
访问OGNL上下文(OGNL context)和ActionContext;
操作集合对象。
在 jsp 中使用 OGNL 需要引入 struts tag lib。
<%@ taglib prefix="s" uri="/struts-tags" %>1
[/code]
然后使用 标签 s:property:
<s:property value="'hello world'"/>1
[/code]
使用引号引起来表示字符串,否则就是 OGNL 表达式
ValueStack
ValueStack 实际是一个接口,在 Struts2 中利用OGNL时,实际上使用的是该接口实现类 OgnlValueStack。每个 Action 类的对象实例都有一个 ValueStack 对象,用于保存参数或结果。
在 ValueStack 对象的内部有两个逻辑部分:
* ObjectStack: Struts 把动作和相关对象压入 ObjectStack 中,看作 List 容器。
* ContextMap: Struts 把各种各样的映射关系存入 ContextMap 中,看作 Map 容器。
Struts2 会把下面这些对象存入 ContextMap 中
* parameters: 该 Map 中包含当前请求的请求参数
* request: 该 Map 中包含当前 request 对象中的所有属性
* session: 该 Map 中包含当前 session 对象中的所有属性
* application:该 Map 中包含当前 application 对象中的所有属性
* attr: 该 Map 按如下顺序来检索某个属性: request, session, application
访问 ValueStack
ObjectStack: 直接通过元素的名称进行访问。ContextMap: 需要在开头加一个
#。
比如 ObjectStack 和 ContextMap 中都存放了一个 User,而 User
有属性 username,那么我们可以通过如下代码进行访问:
jsp 中:
<%--不加修饰符是在栈中查找对象是否有getUsername方法 可以通过 .来指定从第几个开始查找,n从0开始 如果没找到,就会报错 --%> <s:property value="username" /> <%--加修饰符# 是在 map 中查找 key 为 user 的 值 如果存在 session 中,则访问路径为 #session.user.username --%> <s:property value="#user.username" />1
2
3
4
5
6
7
8
9
10
[/code]
Action 中:
ValueStack vs = ActionContext.getContext().getValueStack(); // setValue 方法的第一个参数是 OGNL 表达式,不加#表示放到栈中 vs.setValue("name", "Mike");// 在栈中查找是否有对象有 setName 方法 vs.setValue("#name", "Mike");// 往 map 中存入 key 为 name,值为 Mike 数据。 // set 方法是对 栈 进行操作 // 如果栈顶是 map,则把数据放入map,否则在栈顶新建一个 map,并存入数据。 vs.set("username", "Jane");1
2
3
4
5
6
7
8
[/code]
# $ % 的使用
#1、取 contextMap 中 key 时使用,例如
<s:property value="#name" />
2、OGNL 中创建Map对象时使用,例如:
<s:radio list="#{'male':'男','female':'女'}" />
$
1、在JSP中使用EL表达式时使用,例如
${name}
2、在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。
struts.xml——>${@java.net.URLEncoder.encode(filename)}
%
在struts2中,有些标签的value属性取值就是一个OGNL表达式,例如
<s:property value="OGNL Expression" />
还有一部分标签,value属性的取值就是普通字 符串,例如
<s:textfield value="username"/>,如果想把一个普通的字符串强制看成时OGNL,就需要使用
%{}把字符串套起来。
例如
<s:textfield value="%{username}"/>。当然在
<s:property value="%{OGNL Expression}" />也可以使用,但不会这么用。
投影
“?#”:过滤所有符合条件的集合,如:users.{?#this.age > 19};“^#”:过滤第一个符合条件的元素,如:users.{^#this.age > 19};
“#”:过滤最后一个符合条件的元素,如:users.{#this.age
> 19}
6.Struts 标签
表单标签
常见的表单标签在 struts2 中都有比如: form,textfield,password,checkbox,checkboxlist ,hidden,submit,reset 等。
<s:form action="register"> <s:textfield name="username" label="用户名" requiredLabel="true" requiredPosition="left"/> <s:password name="password" label="密码"/> <s:textfield name="birthday" label="生日"/> <s:checkbox name="married" value="true" label="已婚"/> <s:checkboxlist list="{'吃饭','睡觉','写代码'}" name="hobby" label="爱好" /> <s:select list="#{'BJ':'北京','SH':'上海','SZ':'深圳'}" label="城市" headerKey="" headerValue="---请选择城市---"/> <s:radio name="gender" list="#{'male':'男','female':'女'}" label="性别" value="'male'"/> <s:textarea label="描述" rows="5" cols="30"/> <s:submit value="注册" /> <s:reset value="重置" /> </s:form>1
2
3
4
5
6
7
8
9
10
11
12
[/code]
set
<%-- set 属性详解 value: ognl 表达式,会存入 map 中 var:作为存入 map 数据的 key scope:指定存入的是哪个 map,有 application,session,request,page,action --%> <%-- 并不会往 map 中存入任何值,因为 value 被解释为 OGNL 之后是非法的,所以结果是空 --%> <s:set value="Mike" var="name" scope="session"/> <%-- 加上单引号之后,解释为字符串,存到 session 中 --%> <s:set value="'Mike'" var="name2" scope="session"/> <%-- 不写 scope 默认存到 request 和 contextMap 中了 --%> <s:set value="'Mike'" var="name3"/>1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
action
<%-- action 属性详解 name: action 名称 executeResult: 是否执行 action 一般用于调用其他 action 并在页面上显示结果 --%> <s:action name=="action1" executeResult="true">1
2
3
4
5
6
[/code]
if elseif else
<%--存入一个成绩--%> <s:set var="grade" value="90"/> <s:if test="#grade<60">差</s:if> <s:elseif test="#grade<80">中</s:elseif> <s:else>优秀</s:else>1
2
3
4
5
[/code]
url a
<%-- s:url 属性详解 value: 输出的 value 值。不是 OGNL 表达式 action: action 名称 var: 如果写了,就会把 action 的地址存到 contextMap 中,var 作为 key。 --%> <%-- 指定 value 直接在页面输出 value的值 --%> <s:url value="哈哈哈"/> <br/> <%-- 指定 action 在页面输出 action 的完整地址 --%> <s:url action="addUser1"/> <br/> <%-- 指定了 var 则存到 map 中 --%> <s:url action="addUser1" var="url"> <%--可定义参数,相当于get表单的地址一样--%> <s:param name="name" value="'张三'"/> </s:url> a 标签和 url 类似1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[/code]
7.Validator
struts2为我们共内置了16个验证器,且全部是基于字段的验证器。
required
验证字段的值是不是 null。注意,不是空字符串或空白字符串。<validators> <field name="password"> <field-validator type="required"> <message>The password field is required!</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
[/code]
requiredstring
验证字段的值既不是null、也不是空白。参数:
* fieldName:要验证的字段名
* trim:是否去掉首尾空格
<validators> <field name="userName"> <field-validator type="requiredstring"> <message>Please input the userName!</message> </field-validator> </field> <field name="password"> <field-validator type="requiredstring"> <param name="trim">false</param> <message>Please input the password!</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
10
11
12
13
[/code]
int
验证某个字段的值是否可以被转换为一个整数。还可以验证是否在允许的范围内。参数:
* fieldName:要验证的字段名
* min:允许的最小值
* max:允许的最大值
基于字段的验证
<validators> <field name="age"> <field-validator type="int"> <param name="min">18</param> <param name="max">60</param> <message>The age must be between ${min} and ${max}</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
[/code]
基于验证器的验证
<validators> <validator type="int"> <param name="fieldName">age</param> <param name="min">18</param> <param name="max">60</param> <message>The age must be between ${min} and ${max}</message> </validator> </validators>1
2
3
4
5
6
7
8
[/code]
long short
同 int
double
用来验证某个字段的值是否可以被转换为一个双精度浮点数。还可验证是否在允许的范围内。参数:
* fieldName:要验证的字段名
* minInclusive:允许的最小值,包含最小值
* maxInclusive:允许的最大值,包含最大值
* minExclusive:允许的最小值,不包含最小值
* maxExclusive:允许的最大值,不包含最大值
<validators> <field name="percentage1"> <field-validator type="double"> <param name="minInclusive">20.1</param> <param name="maxInclusive">50.1</param> <message> The age must be between ${ minInclusive } and ${ maxInclusive }(含)</message> </field-validator> </field> <field name="percentage2"> <field-validator type="double"> <param name="minExclusive">0.345</param> <param name="maxExclusive">99.987</param> <message> The age must be between ${ minExclusive } and ${ maxExclusive }(不含)</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
date
用来确保给定的日期字段的值在指定的范围内。参数:
* fieldName:要验证的字段名
* min:允许的最小值,包含最小值
* max:允许的最大值,包含最大值
<validators> <field name="birthday"> <field-validator type="date"> <param name="min">2011-01-01</param> <param name="max">2011-12-31</param> <message>日期必须为2011年</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
[/code]
expression
用于验证是否满足一个OGNL表达式。这是一个非字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个动作错误,因此要显示该错误,需要使用标签。<validators> <validator type="expression"> <param name="expression"> maxNumber>minNumber </param> <message>最大值必须大于最小值</message> </validator> </validators>1
2
3
4
5
6
7
8
[/code]
field expression
用于验证某个字段是否满足一个OGNL表达式。这是一个基于字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个字段错误。参数:
* fieldName:要验证的字段名
* expression:OGNL表达式,只有该表达式为true才能验证通过
<validators> <field name="maxNumber"> <field-validator type="fieldexpression"> <param name="expression"> maxNumber>100 </param> <message>最大值必须大于最小值1</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
10
[/code]
email
用来验证给定的字段是否符合一个Email的规范。它的正则表达式为\\b(^[_A-Za-z0-9-](\\.[_A-Za-z0-9-])*@([A-Za-z0-9-])+((\\.com)|(\\.net)|(\\.org)|(\\.info)|(\\.edu)|(\\.mil)|(\\.gov)|(\\.biz)|(\\.ws)|(\\.us)|(\\.tv)|(\\.cc)|(\\.aero)|(\\.arpa)|(\\.coop)|(\\.int)|(\\.jobs)|(\\.museum)|(\\.name)|(\\.pro)|(\\.travel)|(\\.nato)|(\\..{2,3})|(\\..{2,3}\\..{2,3}))$)\\b1
[/code]
<validators> <field name="email"> <field-validator type="email"> <message>请输入正确的邮箱</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
[/code]
url
用来验证给定的字段值是否是一个合法的URL地址。<validators> <field name="url"> <field-validator type="url"> <message>请输入正确的地址</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
[/code]
visitor
该验证程序可以提高代码的可重用性,你可以利用它把同一个验证程序配置文件用于多个动作。<validators> <field name="streetName"> <field-validator type="requiredstring"> <message>请输入正确街道地址</message> </field-validator> </field> </validators> <validators> <field name="address"> <field-validator type="visitor"> <message>Address:</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
stringlength
用来验证一个非空的字段值是不是有足够的长度。
regex
用来检查给定字段是否与给定的正则表达式相匹配。正则表达式的详细内容可以参考 JDK 的 java.util.regex.Pattern类。
参数:
* fieldname:要验证的字段名
* expression:正则表达式
* caseSensitive:是否区分大小写的情况,默认 true
* trim:是否去掉首尾空格,默认 true
<validators> <field name="userName"> <field-validator type="regex"> <param name="expression"><![CDATA[([aAbBcCdD][123][eEfFgG][456])]]></param> <message> 用户名必须符合规范</message> </field-validator> </field> </validators>1
2
3
4
5
6
7
8
[/code]
8.Interceptor
Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截, Struts2 拦截器是可插拔的, 拦截器是 AOP 的一种实现.
常用拦截器
conversionError:将错误从ActionContext中添加到Action的属性字段中。fileUpload:提供文件上传功能
i18n:记录用户选择的locale
model-driven:如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。
params:将请求中的参数设置到Action中去。
servletConfig:提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。
token:避免重复提交
validation:使用 action-validation.xml 文件中定义的内容校验提交的数据。
workflow:调用 Action 的 validate 方法,一旦有错误返回,重新定位到 INPUT 视图
自定义拦截器
自定义拦截器public class PermissionInterceptor implements Interceptor { private static final long serialVersionUID = -5178310397732210602L; public void destroy() { } public void init() { } public String intercept(ActionInvocation invocation) throws Exception { System.out.println("进入拦截器"); if(session里存在用户){ String result = invocation.invoke(); }else{ return “logon”; } //System.out.println("返回值:"+ result); //return result; } }
在 struts.xml 文件中配置自定义的拦截器
<package name="itcast" namespace="/test" extends="struts-default"> <interceptors> <interceptor name=“permission" class="cn.itcast.aop.PermissionInterceptor" /> <interceptor-stack name="permissionStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name=" permission " /> </interceptor-stack> </interceptors> <action name="helloworld_*" class="cn.itcast.action.HelloWorldAction" method="{1}"> <result name="success">/WEB-INF/page/hello.jsp</result> <interceptor-ref name="permissionStack"/> </action> </package>
9.国际化
struts2 中使用的 properties 文件来做国际化
配置资源包
全局资源包<!-- 在struts.xml 中配置常量指定全局字符串包位置 --> <constant name="struts.custom.i18n.resources" value="com.ittianyu.i18n.strings" />1
2
3
4
[/code]
包范围的资源包:把 资源包放在某包下面,命名为:
package_语言代码_国家代码.properties
局部消息资源包:把 资源包放在某动作类路径下,命名为:
动作类名称_语言代码_国家代码.properties
资源包的使用顺序:局部 > 包范围 > 全局
读取资源包
Actionpublic class I18nAction extends ActionSupport { public String execute() { String value = getText("key"); } }
jsp
<s:text name="key"/>
手动指定读取的资源包
当注定的包下没有找到指定的值时,会按顺序搜索配置了的资源包<s:i18n name="com.xxxx.package"> <s:text name="key"/> </s:i18n>1
2
3
[/code]
10.常见例子
防重复提交
使用重定向,避免刷新就提交<result type="redirect">/success.jsp</result>
使用 tokensession 或 token 拦截器
表单中加入
<s:token />
<s:form action="login"> <s:token /> </s:form>1
2
3
[/code]
配置中加入 tokensession 拦截器
<action name="login" class="xxxx"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="tokensession" /> <result type="redirect">/success.jsp</result> </action>1
2
3
4
5
[/code]
token 和 tokensession 功能一样,但有一些差别。
token 拦截到重复提交后,会转向
invalid.token结果视图
而 tokensession 拦截之后不转向任何视图
上传
html<s:form action="upload.action" enctype="multipart/form-data"> <s:textfield name="username" label="用户名"/> <s:file name="photo" label="照片"/> <s:submit value="上传"/> </s:form>1
2
3
4
5
[/code]
action
public class UploadAction extends ActionSupport{ public String username; public File photo; public String photoFileName;// 上传文件名。变量命名规格 字段名+FileName public String photoContentType;// 上传文件的MIME类型。变量命名规格 字段名+ContentType public String upload() { // 获取文件存储目录 ServletContext servletContext = ServletActionContext.getServletContext(); String path = servletContext.getRealPath("/WEB-INF/files"); File file = new File(path); if (!file.exists()) file.mkdirs(); // 存储到目标路径 photo.renameTo(new File(file, photoFileName)); return NONE; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[/code]
修改上传文件大小限制
<!--限制上传最大尺寸为 1048576 byte--> <constant name="struts.multipart.maxSize" value="1048576"/>1
2
[/code]
限制上传文件扩展名
<action name="upload" class="com.ittianyu.javaeetest.web.action.UploadAction" method="upload"> <interceptor-ref name="defaultStack"> <param name="fileUpload.allowedExtensions">jpg,png</param> </interceptor-ref> <result name="input">upload.jsp</result> </action>1
2
3
4
5
6
[/code]
多文件上传需要把
public File photo; public String photoFileName;// 上传文件名。变量命名规格 字段名+FileName public String photoContentType;// 上传文件的MIME类型。变量命名规格 字段名+ContentType1
2
3
[/code]
改成,也就是改成数组
public File[] photo; public String[] photoFileName;// 上传文件名。变量命名规格 字段名+FileName public String[] photoContentType;// 上传文件的MIME类型。变量命名规格 字段名+ContentType1
2
3
[/code]
下载
actionpublic class DownloadAction extends ActionSupport { public InputStream inputStream; public String filename; public String download() throws Exception{ // 找到文件路径 String path = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/1.jpg"); // 包装成流 inputStream = new FileInputStream(path); // 设置浏览器接收时文件名 filename = "图片.jpg"; return SUCCESS; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
配置
<action name="download" class="com.ittianyu.javaeetest.web.action.DownloadAction" method="download"> <result name="success" type="stream"> <!--下载类型为 bin--> <param name="contentType">application/octet-stream</param> <!--下载打开方式--> <param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename, "UTF-8")} </param> <!--流名称--> <param name="inputName">inputStream</param> </result> </action>
相关文章推荐
- 超全面 struts2 复习总结笔记
- C#面向对象编程全面总结-面试|复习必备
- Struts2 笔记总结
- Struts2总结笔记之一
- 一周一话题之四(JavaScript、Dom、jQuery全面复习总结<jQuery篇>)
- Delphi的学习笔记七——格式化输出函数(总结的很全面)
- 一周一话题之四(JavaScript、Dom、jQuery全面复习总结<js篇>)
- 【笔记总结】struts2标签
- Java复习笔记+经验总结-06 多线程 泛型 反射
- C#面向对象编程全面总结-面试|复习必备
- Java复习笔记+经验总结-04 java异常 常用工具类
- struts2总结笔记之二
- Delphi的学习笔记七——格式化输出函数(总结的很全面)
- 全面复习之 java IO流总结
- C语言复习笔记三:三种程序结构记习题总结(1)
- 【ibokan】HTMl常用标签复习总结笔记
- struts2笔记总结
- struts2复习(五)拦截器总结
- struts2复习(五)拦截器总结
- javascript 复习笔记----注意事项总结