- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Struts 2 数据校验功能及校验问题的解决方案由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
通过继承ActionSupport类来完成Action开发,ActionSupport类不仅对Action接口进行简单实现, 同时增加了验证、本地化等支持 。真实开发中自定义Action都需要继承该类。对用户登录添加表单验证功能 。
ActionSupport类的作用:
struts2不要求我们自己设计的action类继承任何的struts基类或struts接口,但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。 Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法.
那么Action 接口和 ActionSupport类的区别是什么呢?
Action接口有
1
2
3
4
5
|
public
static
final
String SUCCESS =
"success"
;
public
static
final
String NONE =
"none"
;
public
static
final
String ERROR =
"error"
;
public
static
final
String LOGIN =
"login"
;
public
String execute()
throws
Exception;
|
可以看到有五个静态常量和返回类型为String 的execute() 。
而Actionsupport这个工具类在实现了Action接口的基础上还定义了一个validate()方法,重写该方法,它会在execute()方法之前执行,如校验失败,会转入input处,必须在配置该Action时配置input属性.
另外,Actionsupport还提供了一个getText(String key)方法还实现国际化,该方法从资源文件上获取国际化信息. 。
这样在自定义标签时可以定义一个变量为new actionsupport对象实现国际化.
Actionsupport类有(源码):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
public
class
ActionSupport
implements
Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
protected
static
Logger LOG = LoggerFactory.getLogger(ActionSupport.
class
);
private
final
ValidationAwareSupport validationAware =
new
ValidationAwareSupport();
private
transient
TextProvider textProvider;
private
Container container;
public
void
setActionErrors(Collection<String> errorMessages) {
validationAware.setActionErrors(errorMessages);
}
public
Collection<String> getActionErrors() {
return
validationAware.getActionErrors();
}
public
void
setActionMessages(Collection<String> messages) {
validationAware.setActionMessages(messages);
}
public
Collection<String> getActionMessages() {
return
validationAware.getActionMessages();
}
@Deprecated
public
Collection<String> getErrorMessages() {
return
getActionErrors();
}
@Deprecated
public
Map<String, List<String>> getErrors() {
return
getFieldErrors();
}
public
void
setFieldErrors(Map<String, List<String>> errorMap) {
validationAware.setFieldErrors(errorMap);
}
public
Map<String, List<String>> getFieldErrors() {
return
validationAware.getFieldErrors();
}
public
Locale getLocale() {
ActionContext ctx = ActionContext.getContext();
if
(ctx !=
null
) {
return
ctx.getLocale();
}
else
{
if
(LOG.isDebugEnabled()) {
LOG.debug(
"Action context not initialized"
);
}
return
null
;
}
}
public
boolean
hasKey(String key) {
return
getTextProvider().hasKey(key);
}
public
String getText(String aTextName) {
return
getTextProvider().getText(aTextName);
}
public
String getText(String aTextName, String defaultValue) {
return
getTextProvider().getText(aTextName, defaultValue);
}
public
String getText(String aTextName, String defaultValue, String obj) {
return
getTextProvider().getText(aTextName, defaultValue, obj);
}
public
String getText(String aTextName, List<?> args) {
return
getTextProvider().getText(aTextName, args);
}
public
String getText(String key, String[] args) {
return
getTextProvider().getText(key, args);
}
public
String getText(String aTextName, String defaultValue, List<?> args) {
return
getTextProvider().getText(aTextName, defaultValue, args);
}
public
String getText(String key, String defaultValue, String[] args) {
return
getTextProvider().getText(key, defaultValue, args);
}
public
String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
return
getTextProvider().getText(key, defaultValue, args, stack);
}
public
String getText(String key, String defaultValue, String[] args, ValueStack stack) {
return
getTextProvider().getText(key, defaultValue, args, stack);
}
public
String getFormatted(String key, String expr) {
Map<String, Object> conversionErrors = ActionContext.getContext().getConversionErrors();
if
(conversionErrors.containsKey(expr)) {
String[] vals = (String[]) conversionErrors.get(expr);
return
vals[
0
];
}
else
{
final
ValueStack valueStack = ActionContext.getContext().getValueStack();
final
Object val = valueStack.findValue(expr);
return
getText(key, Arrays.asList(val));
}
}
public
ResourceBundle getTexts() {
return
getTextProvider().getTexts();
}
public
ResourceBundle getTexts(String aBundleName) {
return
getTextProvider().getTexts(aBundleName);
}
public
void
addActionError(String anErrorMessage) {
validationAware.addActionError(anErrorMessage);
}
public
void
addActionMessage(String aMessage) {
validationAware.addActionMessage(aMessage);
}
public
void
addFieldError(String fieldName, String errorMessage) {
validationAware.addFieldError(fieldName, errorMessage);
}
public
String input()
throws
Exception {
return
INPUT;
}
public
String doDefault()
throws
Exception {
return
SUCCESS;
}
public
String execute()
throws
Exception {
return
SUCCESS;
}
public
boolean
hasActionErrors() {
return
validationAware.hasActionErrors();
}
public
boolean
hasActionMessages() {
return
validationAware.hasActionMessages();
}
public
boolean
hasErrors() {
return
validationAware.hasErrors();
}
public
boolean
hasFieldErrors() {
return
validationAware.hasFieldErrors();
}
public
void
clearFieldErrors() {
validationAware.clearFieldErrors();
}
public
void
clearActionErrors() {
validationAware.clearActionErrors();
}
public
void
clearMessages() {
validationAware.clearMessages();
}
public
void
clearErrors() {
validationAware.clearErrors();
}
public
void
clearErrorsAndMessages() {
validationAware.clearErrorsAndMessages();
}
public
void
validate() {
}
@Override
public
Object clone()
throws
CloneNotSupportedException {
return
super
.clone();
}
public
void
pause(String result) {
}
private
TextProvider getTextProvider() {
if
(textProvider ==
null
) {
TextProviderFactory tpf =
new
TextProviderFactory();
if
(container !=
null
) {
container.inject(tpf);
}
textProvider = tpf.createInstance(getClass(),
this
);
}
return
textProvider;
}
@Inject
public
void
setContainer(Container container) {
this
.container = container;
}
|
可以看到里面有很多的方法,但我们很明显看到有一个我们很了解的,validate(),数据校验的方法。通过这个方法,我们可以登录时,用户名和密码为空的提示,或其他·· 。
现在举一个简单的例子:当用户名和密码为空,给客户一个友好提示.
下面通过两种方式来阐述Struts 2的数据校验功能.
1. 编码方式校验 。
1) Action一定要继承自ActionSupport 。
2) 针对某个要进行校验的请求处理方法编写一个 public void validateXxx()方法,在方法内部进行表单数据校验. 。
3) 也可针对所有的请求处理方法编写public void validate()方法.
4) 在校验方法中,可以通过addFieldError()方法来添加字段校验错误消息.
5) 当校验失败时,Struts框架会自动跳转到name为input的Result页面。在校验失败页面中,可以使用<s:fielderror/>来显示错误消息 6) 简单,灵活。但重用性不高 。
重写validate方法 。
1.我们编写的Action一般继承与ActionSupport,而ActionSupport不仅实现了Action接口,还实现了Validatable接口,提供了数据校验功能。在Validatable接口中定义一个validate方法,重写该方法,如果校验表单输入域出现错误,则将错误添加到ActionSupport类的fieldError域中,然后通过OGNL表达式输出.
下面是用户登录校验界面:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<body>
<%--输出校验信息--%>
<%--想要单个提示 <s:fielderror fieldName=
"uname"
/>--%>
<%--<s:property value=
""
/>
--%><div style=
"color:red"
><s:fielderror/></div>
<s:form name=
"form1"
namespace=
"/"
method=
"post"
action=
"LoginValidateAction"
>
<s:div>请输入用户名:<s:textfield name=
"user.uname"
></s:textfield></s:div>
<s:div>请输入密码:<s:password name=
"user.upwd"
></s:password></s:div>
<s:submit value=
"登录"
></s:submit>
</s:form>
<%--debug --%>
<s:debug></s:debug>
</body>
|
用户输入数据后,提交到LoginValidateAction 中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public
class
LoginValidateAction
extends
ActionSupport
implements
Action {
public
User user;
public
Map<String, Object> map;
//验证的方法,会对所有的Action起作用
@Override
public
void
validate() {
if
(user.getUname().length()==
0
){
addFieldError(
"uname"
,
"用户名不能为空!"
);
}
if
(user.getUpwd().length()==
0
){
addFieldError(
"upwd"
,
"密码不能为空!"
);
}
}
//处理业务的方法
public
String execute()
throws
Exception {
System.out.println(user.getUname());
if
(user.getUname().equals(
"admin"
)&&user.getUpwd().equals(
"admin"
)){
//让Struts2注入 map集合
map.put(
"uname"
, user.getUname());
//如果登录成功,返回“ success”
return
SUCCESS;
}
else
{
//登录失败,返回 error
return
INPUT;
//此处一定是 input
}
}
/**
* @return the user
*/
public
User getUser() {
return
user;
}
/**
* @param user the user to set
*/
public
void
setUser(User user) {
this
.user = user;
}
|
上面的LoginValidateAction类重写了validate方法,该方法会在执行excute方法之前执行,如果执行该方法之后,Action类的filedError中包含了数据校验错误,请求将被转发到input逻辑视图.
struts.xml配置如下:
1
2
3
4
5
6
7
8
9
|
<!-- 数据校验 -->
<action name=
"LoginValidateAction"
class
=
"cn.struts2.action.LoginValidateAction"
>
<!-- 结果为“success”时,跳转至success.jsp页面 -->
<result name=
"success"
>success.jsp</result>
<!-- 结果为
"error"
时,跳转至fail.jsp页面 或 还在登录界面 login.jsp-->
<result name=
"input"
>LoginValidateAction.jsp</result>
<result name=
"login"
>fail.jsp</result>
<result name=
"error"
>fail.jsp</result>
</action>
|
在客户端的效果:
但是大家注意没有呢,当提示错误的时候不太是我们想要的的效果显示.
这个不是我们所想要的,那么我们怎么改呢?其实这主要显示的struts2主题样式导致的, 。
再来看看:
它自动给我们添加了样式。struts2提供了三种主题,ajax, simple, xhtml,它默认的是xhtml主题,当然你可以写任意个你自己的主题,我们称之为自定义主题。可以通过设置解决以上问题 。
有两种方法可以解决:
1.简单的方法(也很实用,针对所有struts2标签),在Struts.xml中,加上下一行代码就可以了.
1
|
<constant name=
"struts.ui.theme"
value=
"simple"
/>
|
代表所有的页面采用的都是 simple主题了,这时它输出的页面,不回添加任何多余的代码,比如 table tr td 等,我们就可以像其他编辑页面的方式编辑页面的风格.
现在再来看看,错误的提示格式 。
我们可以通过设置这样一个标签:
1
|
<s:property value=
"errors.uname[0]"
/>
|
把这个标签注释掉:
1
|
<div style=
"color:red"
><s:fielderror/></div>
|
但我们设置成 这样时,会出现这样的效果.
这种效果就有点想我们平常输入错误时的那个提示了,还有其他属性值,这里就不用一一列举了.
使用Struts2的校验框架 。
XML配置方式校验.
在编码方式之前被执行.
1) 针对要校验的Action类,在同包下编写一个名为:Action类名-validation.xml校验规则文件.
2) 在校验规则文件中添加校验规则:具体的校验器名,参数可参看Struts2的reference或Struts2的API.
a) Field校验:针对Action类中每个非自定义类型的Field进行校验的规则.
1
2
3
4
5
6
7
|
<field name=
"要校验的Field名"
>
<field-validator type=
"校验规则器名"
short
-circuit=
"是否要短路径校验(默认是false)"
>
<param name=
"校验器要使用的参数名"
>值</param>
<message>校验失败时的提示消息</message>
</field-validator>
<!-- 还可添加其它的校验规则 -->
</field>
|
b) 非Field校验:针对Action类的某些Field使用OGNL表达进行组合校验.
1
2
3
4
5
6
|
<validator type=
"fieldexpression"
>
<param name=
"fieldName"
>pwd</param>
<param name=
"fieldName"
>pwd2</param>
<param name=
"expression"
><![CDATA[pwd==pwd2]]></param><!-- OGNL表达式 -->
<message>确认密码和密码输入不一致</message>
</validator>
|
c) visitor校验:主要是用来校验Action类中的自定义类型Field。(针对使用模型驱动方式时) 。
i) 在Action类的的校验规则文件中针对自定义类型Field使用visitor校验规则.
1
2
3
4
5
6
7
8
9
10
11
|
<!-- 针对自定义Field使用visitor校验 -->
<field name=
"user"
>
<field-validator type=
"required"
short
-circuit=
"true"
>
<message>用户的信息必填</message><!-- 消息前缀 -->
</field-validator>
<field-validator type=
"visitor"
><!-- 指定为visitor校验规则 -->
<param name=
"context"
>userContext</param><!-- 指定本visitor校验的上下文名 -->
<param name=
"appendPrefix"
>
true
</param><!-- 是否要添加校验失败消息的前缀 -->
<message>用户的</message><!-- 消息前缀 -->
</field-validator>
</field>
|
ii) 针对visitor的Field编写一个校验规则文件.文件名为: visitor字段类型名[-visitor校验的上下文名]-validation.xml. 例如: 本例中的文件名为User-userContext-validation.xml 。
注意: 此文件要存放到visitor字段类型所在的包下. 。
iii) 在visitor的Field校验规则文件中针对要校验的Field添加校验规则. 。
我们还可以不重写validate方法,而通过增加校验配置文件来进行数据校验。这个校验配置文件通过使用Struts2已有的校验器来完成对表单域的校验,下面以requiredstring校验器为例,这个校验器是一个必填校验器,指定某个表单域必须输入.
下面是这个校验配置文件LoginValidateAction-validation.xml的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"
>
<validators>
<field name=
"uname"
>
<field-validator type=
"requiredstring"
>
<message>用户名不能为空</message>
</field-validator>
</field>
<field name=
"upwd"
>
<field-validator type=
"requiredstring"
>
<message>密码不能为空</message>
</field-validator>
<field-validator type=
"stringlength"
>
<param name=
"maxLength"
>
18
</param>
<param name=
"minLength"
>
6
</param>
<message>密码长度应该在${minLength}--${maxLength}位之间</message>
</field-validator>
</field>
</validators>
|
注意:这个校验配置文件必须遵守下面两个规则:
1、该文件命运格式必须是Action类名-validation.xml,例如本例中该文件名为:LoginValidateAction-validation.xml 。
2、该文件必须与Action类的class文件位于同一路径下,本例中文件位于 。
LoginValidateAction类的代码还是一样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public
class
LoginValidateAction
extends
ActionSupport
implements
Action {
public
User user;
public
Map<String, Object> map;
//验证的方法,会对所有的Action起作用
@Override
public
void
validate() {
if
(user.getUname().length()==
0
){
addFieldError(
"uname"
,
"用户名不能为空!"
);
}
if
(user.getUpwd().length()==
0
){
addFieldError(
"upwd"
,
"密码不能为空!"
);
}
}
//处理业务的方法
public
String execute()
throws
Exception {
System.out.println(user.getUname());
if
(user.getUname().equals(
"admin"
)&&user.getUpwd().equals(
"admin"
)){
//让Struts2注入 map集合
map.put(
"uname"
, user.getUname());
//如果登录成功,返回“ success”
return
SUCCESS;
}
else
{
//登录失败,返回 error
return
INPUT;
//此处一定是 input
}
}
/**
* @return the user
*/
public
User getUser() {
return
user;
}
/**
* @param user the user to set
*/
public
void
setUser(User user) {
this
.user = user;
}
|
以上所述是小编给大家介绍的Struts 2 数据校验功能及校验问题的解决方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。
原文链接:http://www.cnblogs.com/whyhappy/p/5831937.html 。
最后此篇关于Struts 2 数据校验功能及校验问题的解决方案的文章就讲到这里了,如果你想了解更多关于Struts 2 数据校验功能及校验问题的解决方案的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在构建一个 RCP 应用程序,其中每个季度都会更新功能/插件。因此,如果用户选择自动更新功能/插件,则会下载更新插件的新 jar,但旧插件仍在使用我不再使用的磁盘空间。 我厌倦了删除包含旧 jar
我如何从外部 Controller 功能中调用 Controller 内部的功能,例如电话间隙回调功能 这是 Controller 外部定义的功能 function onDeviceReady()
如果某个功能(例如 MediaSource)可用,我如何使用 Google Dart 检查。 new MediaSource() 抛出一个错误。如何以编程方式检查此类或功能是否存在?有任何想法吗?是否
我正在尝试运行 Azure Orchestrations,突然我开始从 statusQueryGetUri 收到错误: 协调器函数“UploadDocumentOrchestrator”失败:函数“U
我见过 iPhone 上的应用程序,如果在 3.0 上运行,将使用 3.0 功能/API,例如应用内电子邮件编辑器,如果在 2.x 上运行,则不使用这些功能,并退出应用程序以启动邮件相反。 这是怎么做
这是 DB 规范化理论中的一个概念: Third normal form is violated when a non-key field is a fact about another non-ke
如果我定义 #if SOMETHING #endif 而且我还没有在任何地方定义 SOMETHING。 #if 中的代码会编译吗? 最佳答案 当#if的参数表达式中使用的名称未定义为宏时(在所有其他宏
我刚刚澄清了 A* 路径查找应该如何在两条路径具有相等值的 [情况] 下运行,无论是在计算期间还是在结束时,如果有两条相等的短路径。 例如,我在我的起始节点,我可以扩展到两个可能的节点,但它们都具有相
Java有没有类似下面的东西 宏 一种遍历所有私有(private)字段的方法 类似于 smalltalk symbols 的东西——即用于快速比较静态字符串的东西? 请注意,我正在尝试为 black
这个程序应该将华氏度转换为摄氏度: #include int main() { float fahrenheit, celsius; int max, min, step;
当打开PC缓存功能后, 软件将采用先进先出的原则排队对示波器采集的每一帧数据, 进行帧缓存。 当发现屏幕中有感兴趣的波形掠过时, 鼠标点击软件的(暂停)按钮, 可以选择回看某一帧的波形
我有一个特殊的(虚拟)函数,我想在沙盒环境中使用它: disable.system.call eval(parse(text = 'model.frame("1 ~ 1")'), envir = e
使用新的 Service 实现,我是否必须为我的所有服务提供一个 Options 方法? 使用我的所有服务当前使用的旧 ServiceBase 方法,OPTIONS 返回 OK,但没有 Access-
我正在阅读 Fogus 的关于 Clojure 的喜悦的书,在并行编程章节中,我看到了一个函数定义,它肯定想说明一些重要的事情,但我不知道是什么。此外,我看不到这个函数有什么用 - 当我执行时,它什么
我有大量的 C 代码,大部分代码被注释掉和/或 #if 0。当我使用 % 键匹配 if-else 的左括号和右括号时,它也匹配注释掉的代码。 有没有办法或vim插件在匹配括号时不考虑注释掉或#if 0
我有这个功能: map(map(fn x =>[x])) [[],[1],[2,3,4]]; 产生: val it = [[],[[1]],[[2],[3],[4]]] 我不明白这个功能是如何工作的。
我使用 Visual Studio 代码创建了一个函数应用程序,然后发布了它。功能应用程序运行良好。我现在在功能门户中使用代码部署功能(KUDU)并跳过构建。下面是日志 9:55:46 AM
我有一个数据框df: userID Score Task_Alpha Task_Beta Task_Charlie Task_Delta 3108 -8.00 Easy Easy
我真的无法解决这个问题: 我有一个返回数据框的函数。但是,数据框仅打印在我的控制台中,尽管我希望将其存储在工作空间中。我怎样才能做到这一点? 样本数据: n <- 32640 t <- seq(3*p
有没有办法找出所有可能的激活器命令行选项? activator -help仅提供最低限度的可用选项/功能列表,但所有好的东西都隐藏起来,即使在 typesafe 网站在线文档中也不可用。 到目前为止,
我是一名优秀的程序员,十分优秀!