Struct 总结:
Struts2 总结
1. Action
a) namespace (掌握)
b) path (掌握)
c) DMI (掌握)
d) wildcard (掌握)
e) 接收参数(掌握前两种)
f) 访问 request 等(掌握 Map IOC 方式)
g) 简单数据验证(掌握 addFieldError 和 <s:fieldError )
1. Result
a) 结果类型(掌握四种,重点两种)
b) 全局结果(掌握)
c) 动态结果(了解)
1. OGNL 表达式(精通)
a) # % $
2. Struts 标签
a) 掌握常用的
3. 声明式异常处理(了解)
4. I18N (了解)
5. CRUD 的过程(最重要是设计与规划)(精通)
6. Interceptor 的原理(掌握)
7. 类型转换(掌握默认,了解自定义)
Struct 1 Action
每次请求时,都只会用原先那个 Action 类生成的实例
Struct 2 Action
每次请求时,都会重新生成 Action 类的实例
实际上主流的开发 有两个方向:
1. 轻量级、开源框架:以 Spring+Hibernate 为基础的。
2. Sun 公司提供的 Java EE 规范:以 EJB 3+JPA 为基础的。
Struts 2 和 Xwork [X1]
Struts 2 是由 WebWork 发展而来的, WebWork 是以 XWork 为基础的。
所以 Struts 2 也是以 XWork 为基础的。
安装 struts 2
( 1 ) 拷 JAR 包 [X2] 。
( 2 ) 修改 web.xml 文件,增加 Struts2 支持。 DEMO
需要在 web.xml 文件中增加一个核心 Filter 。以前是 FilterDispatcher ,
现在改为使用 StrutsPrepareAndExecuteFilter 。
但实际上, 2.1.6 中依然不能使用 StrutsPrepareAndExecuteFilter ,因为它在处理中文问题时有乱码。
( 3 ) 在 WEB-INF/classes 目录增加一个 struts.xml 文件,它负责管理 Struts 2 的配置。
struts.xml 是开发过程中一个非常重要的配置文件。
1. 注册(插入一条记录) 2. 登录(查看指定记录是否存在) 3. 查看 / 修改用户。(查询全部记录)
struts2-core-2.1.8.1.jar
xwork-core-2.1.6.jar
freemarker-2.3.15.jar
ognl-2.7.3.jar
commons-fileupload-1.2.1.jar
commons-logging-1.0.4.jar
与传统 MVC 开发的差别:
1. 传统的 MVC 开发,每次用户请求,通常会定义一个 Servlet 进行处理。
用了 Struts 2 之后,定义一个 Action 进行处理。
2. 传统的 MVC 开发, Servlet 开发完成之后,需要在 web.xml 文件中配置 Servlet
用了 Struts 2 之后,需要在 struts.xml 文件中配置 Action
Struts 2 的 Action 的要求:
1. 实现 Action 接口,或者继承 ActionSupport 基类 [X1]
2. 为所有的请求参数定义 Field ,并提供 getter 和 setter 方法。
以后就可通过该 Field 来获取请求参数,无需搞 request .getParameter [X2] !!!!
3. 定义一个处理用户请求的方法。该方法的签名是:
public String xxx() execute
{
}
用了 Struts 2 之后 [X3] ,
在 Action 类中,无需通过 getParameter 来获取请求参数。
也不需要调用 request.setAttribute 将需要显示的数据传到 JSP 页面。
<!-- 配置列出 Web 应用根路径下所有文件的 Action -->
<action name="">
<result>.</result>
</ action [X4] >
虽然 action 的命名空间非常灵活,但如果 name 用带 . 或 - 的值,则可能引发其他异常
原则:约定优于配置
常量配置:
它就是一些简单的 key - value 对!
通常就是一个常量名、一个常量值。
为 struts 2 配置 常量有 3 种方式:
↗ 在 web.xml 文件中为 PrepareAndExecuteFilter 指定初始化参数。
每个 <init-param.../> 元素配置一个常量。
↗ 增加一个 struts.properties 文件(放在 WEB-INF/classes )。
struts.i18n.encoding =UTF-8 指定默认编码集
struts.action.extension = 扩展名 默认是 action
structs.i18n.reload = 是否每次 HTTP 请求到达时,系统自动加载资源文件
structs.configuratin.xml .reload 当 XML 文件改变后,系统是否自动重新加载此文件。
structs. i18n.resources 所需要的国际第资源文件,如果有多个资源文件则用 , 分开
struts.devMode =true 是否使用开发模式。如果为 true 则可以在应用出错时显示更多、更友好的出错提示。
通常开发阶段设为 true ,开发阶段设为 false
↗ 在 struts .xml 文件中使用 <constant .../> 元素进行配置。
<constant name="struts.i18n.encoding" value ="GBK"/>
<constant name="struts.action.extension" value ="html"/>
包含其他配置文件:
默认情况下, Struct2 会自动加载类加载路径下的 structs.xml default.xml stuts-plugin.xml 三类文件 [X1]
通常, structs2 框架按如下顺序加载 Struct2 常量:
Structs-default.xml (保存在 struts2-core-2.1.2 文件中)
Structs-plugin.xml (保存在 struts2-Xxxx-2.1.2 等 struct2 插件 JAR 文件中)
Structs.xml
Structs.properties ( stucts2 默认的配置文件)
Web.xml
<include file=”struts-part1.xml > DEMO
包,抽象包不能用 action (包和命名空间) (“” 默认命名空间可以处理任何命名空间的请求 )
Struct2 还可以显示指定根命名空间,通过设置某个包的 namespace=”/” 来指定根命名空间。
如果请求为 /barspace/bar.action ,系统首先查找 /barspace 空间下的 bar.action 请求,如果在此命名空间里找不到,则到默认的命名空间里找,都找不到的就出错。
如果请求为 /login.action ,系统会在根命名空间下(“ / ”)查找名为 login 的 Action ,找到了就处理此请求,否则到默认的命名空间里找,都长不到的就出错。
命名空间只有一个级别。如果请求的 URL 是 /bookservice/search/get.action ,系统将先在 /bookservice/search 的命名空间下查找名为 get 的 Action ,没有的就到默认的空间找,而不会到 //bookservice 的命名空间下查找。。。。
Struts 2 不允许为单独的 Action 配置命名空间,只能为一个 package 整体配置命名空间。
Struts 2 的核心 JAR 包里包含了一个 struts-default.xml 文件,
该文件中定义了一个名为 struts-default 的抽象包。
设置默认的 Action
为了让 Struct2 的 Action 可以接管用户请求,我们可以配置 name =”*” 的 Action ,
除此之外, Struct2 还支持配置默认 Action ,当用户请求找不到对应的 Action 时,系统默认的 Action 即将处理用户请求
<default-action-ref name=”simpleCddfsdf”>
<action name="simpleCddfsdf" class="lee.simpleCddfsdf" >
<result ... />
</action>
实现 Action :
Struct2 2 的 Action 优势:
低侵入式设计。代码的保值性很好;
与 Servlet API 分离,便于测试
Action 访问 Servlet API [X1] :
Web 应用中通常访问的 API 是: HttpServletRequest 、 HttpSession 、 ServletContext( 代表 application 对象 )
既可以彻底与 Servlet Api 分离,从而允许此 Action 脱离 Web 容器运行,也就可以脱离 Web 容器来测试 Action ,又允许用简单的方式操作各范围内属性
两种方式:
1 借助 ActionContext 实现伪访问 DEMO jsp
2 借助 ServletActionContext 实现真实访问
借助 ServletContextAware :实现此接口可以直接访问 ServletContext 实例 DEMO
借助 ServletRequestAware :直接访问 HttpRequest 实例
借助 ServletResponseAware [X1] :
DMI 动态方法调用: ! 好像用处不大 跟 method 差不多 在浏览器 URL 里可以用 ..!..
使用动态方法调用前必须设置 struts.enable.DynamicMethodInvocation = true
指定 Method 属性及使用通配符:
如果省略了 method 属性,则默认采用 execute 方法处理请求
<action name=" * Action" class="lee.LoginRegistAction" method ="{ 1 }">
<action name=" * - * " class="action.{1 }" method ="{ 2 }">
<!— 通用的 Action -->
<action name=”*”> <result>/{1}.jsp</result> </action>
<action name=””>
<result>.</result>
</action>
<!— 浏览器 列出当前目录 -->
配置处理结果:
Action 的处理方法的签名必须为如下格式:
public String xxx()
{
}
配置结果有两种方式 [X2] :
局部结果: 将 <result.../> 元素作为 <action.../> 元素的子元素定义。
全局结果: 将 <result.../> 元素作为 <global-results..../> 元素的子元素定义。
<gloabl-results>
<result name="success">/WEB-INF/jsp/{1}Succ.jsp</result>
</gloabl-results>
Result 默认的 name 属性名是 sussecc ,可以省略的
局部结果只对当前 <action.../> 配置起作用。
全局结果则对所有的 <action.../> 配置都起作用。
当局部结果和全局结果冲突时,局部结果生效!!!!
配置结果的完整语法为:
< result name="Action 处理方法所返回的字符串 " type=" 视图类型 ">
<!-- location 参数指定视图资源的位置 -->
< param name=" locatioin ">/ 视图资源的位置 </param>
<param .../>
</result>
- name 属性指定 Action 处理方法所返回的字符串,该属性的默认值是 " success "
- type 指定将要使用的视图资源的类型,该属性的默认值是 " dispatcher "
如果配置 <result.../> 时,只需要一个 < param.. ./> 子元素,
而且该 <param.../> 元素所配置的参数名为 location ,那么可以简写为如下形式:
<result name =" Action 处理方法所返回的字符串 " type =" 视图类型 ">/ 视图资源的位置 </result>
Struts 2 支持的结果类型 :
chain :使用两个 Action 作为链来处理。一个用户请求,需要先后经过两个或更多的 Action 处理。
就要用到这种 chain 处理结果。
dispatcher :默认的处理结果。 ( 转发 )
freemarker
httpheader
redirect :重定向另一个 URL 。 Jsp ( 重定向 [X1] )
<result name="success" type="redirect">
<param name="location">foo.jsp</param>
<param name="parse ">false</param>
</result>
<!—parse
是否允许在location
参数中使用表达式
-->
stream :做文件下载的。
velocity
xslt
plainText :使用普通文本作为视图。 ( 主要用于显示实际视图资源的源代码 [X1] )
动态结果 : *
“ 零配置 ” the Convention Plugin is bundled with Struts since 2.1 and replaces the Codebehind Plugin and Zero Config plugins. It provides the following features: ( 代替了零配置插件 )
------------------------------------
用 Annotation 来代替了 XML 配置。
Rails 框架, “CoC” Convention Over Configuration
使用 XML 配置的优势是:
管理信息从 Java 源代码中分离出来。因此降低了耦合,从提高了可扩展性。
使用 XML 配置的劣势是:
a. 重写编写 XML 工作量大,开发效率低。
b. XML 文件越来越多,维护 XML 文档也变得很难。
Rails 说:有一个约定。
Convention Over Configuration 约定优于配置。
Struts 2 的工具插件 :
struts2-config-browser-plugin-2.1.8.1.jar
configBrowser 插件的用法:
1. 将插件的 JAR 包复制到 Web 应用 WEB-INF/lib 下。
2. 访问主机名 : 端口 / 项目名 /config-browser/index
这个插件的作用是帮助你调试的。
Convention
插件。 (
约定插件,不叫零配置)
<constant name="struts.convention.result.path" value="/WEB-INF/jsp/"/> //XML 文件
@ResultPath("/WEB-INF/jsps") // 放在 Actin 类前面
<!-- 系统自动搜索的 Action 类的后缀 -->
<constant name="struts.convention.action.suffix" value="Action"/>
<!-- 系统自动搜索的 Action 类所在的子包 -->
<constant name="struts.convention.action.packages" value="actions"/>
<!-- 指定是否自动搜索所有匹配的 action -->
<constant name="struts.convention.action.mapAllMatches" value="true"/>
1. Action 类必须满足一定的规则。
2. Action 类通常应该放在 actions 子包下。
这样 Convention 插件会自动搜索所有匹配的 Action ,并将其进行“配置”
将 Action 的类名的后缀去掉,并将原来的“ camerl ”写法,改为中划线写法,
作为 <action.../> 的 name
在 struts-defult.xml 里已经配置了开启异常映射功能
<interceptors> <interceptor name=”exception” class=” ”
局部异常映射: < exception - mappting > 作为 < action > 子元素配置 [X2]
<action><exception-mappting exception =”java.sql.SQLException” result=”sql” /><action>
全局异常映射: <exception-mappting> 作为 < global - exception - mapping > 子元素配置
<global-exception-mapping><exception-mappting exception =”java.sql.SQLException” result=”sql” /><global-exception-mapping>
输出异常信息: ( 可直接放在JSP 页面中) 要先导入标签库 <%@ taglib prefix=”s” uri=”/struts-tags” %>
<s:property value=”exception”> 输出异常对象本身
<s:property value=”exceptionStack”> 输出异常堆栈信息
<s:property value=”exception.message ”>
<s:property value=”exceptionStack”> 使用 Structs2 标签输出异常跟踪栈信息
全局异常映射的 result 属性值通常不要使用局部结果,局部映射的 result 属性值既可以使用全局结果集,也可以使用局部结果集
Struts2 国际化:
Sruts.custom.i18n.resource = messageResource 使用 native2ascii 工具 [X1]
访问国际化信息: messageResouce.properties _zh_CN.properties _en_US.properties
JSP 页面, <s:text name=”” /> name 指定了国际化资源文件中的 key DEMO
Action 类, 使用 ActionSupport 类的 getText 方法 name 属性 name 指定了国际化资源文件中的 key
在此表单元素的 Label 里输出国际化信息,可以为此表单标签指定一个 key 属性,此 key 指定了国际化资源文件中的 key <s:textfield name="username" key="user"/>
输出带占位符的国际化消息: DEMO
JSP 页面, <s: text ../> 标签中 使用多个 <s: param ../> 依此类推的
Action 类, getText 来自于 ActionSuport
加载资源文件的方式:
1. 全局资源 需要显式加载 利用这个常量 Sruts.custom.i18n.resource
2. 包范围的国际化资源 ( 资源文件放在此包;命名 PackageName_language_country.properties )
3. Action 范围内国际化资源 ( 资源文件与 Action 类放在一起;命名 ActionName_language_country.properties )
4. 页面范围 ( 局部 ) 国际化资源 ( 临时 [X2] ) <s:i18n > 作为父标签,通过这个标签显式加载 DEMO
页面上使用 <s:text> 标签来输出国际化消息,
当此标签在资源文件找不到对应的 key ,它将直接输出默认消息,如果默认消息也没有,它将输出 key
Struts 标签库 :
OGNL 表达式
Stack Context 中有两个对象, foo 和 bar ,其中 foo 是根。
#foo.abc - 输出 foo.getAbc()
#bar.abc - 输出 bar.getAbc()
OGNL 规定, 如果省略对象,那么默认就是访问根 的属性。
abc - 输出 foo.getAbc()
如果 Stack Context 有 2 个根: foo , bar (根之间有顺序)
#foo.abc - 输出 foo.getAbc()
#bar.abc - 输出 bar.getAbc()
abc - 优先输出 foo.getAbc(), 如果 foo 对象没有 getAbc(), 尝试输出 bar.getAbc()
Struts 2 的 OGNL 求值是基于 Stack Context
在 Struts 2 中, Stack Context 的第一个根对象是 Value Stack , Value Stack 里又包含大量对象。
如果需要访问 ValueStack 里的属性,只需通过以下方式即可:
${bar}
Struts 还提供了一些 命名对象 ,这些命名对象与根对象无关,它们只是存在于 StackContext 中。所以访问这些对象时需要使用 # 前缀来指明:
Parameters #Parameters ["foo"] 或 #Parameters.foo
Request #request ["ddd"] 或 #request.ddd
Session
Application
Attr 此对象将依次搜索如下对象: PageContext HttpServlet HttpSession ServletyContext 中的属性
Debuger 调试标签 <s:debug />
OGNL 中的集合操作
创建 List 集合 {e2 , e2 , ...}
创建 Map 类型集合 # {key1:value1 , key2:value2 , ....}
取得子集时有如下3 个操作符:
? 取出所有符合选择逻辑的元素 person.relatives.{ ? #this.gender == ‘male’ }
^ 取出符合选择逻辑的第一个元素
$ 取出符合选择逻辑的最后一个元素
对于集合类型, OGNL 表达式可以使用 in 和 not in 两个元素符号。其中, in 表达式用来判断某个元素是否在指定的集合对象中; not in 判断某个元素是否不在指定的集合对象中,
%” 符号的用途是在标志的属性为字符串类型时,计算 OGNL 表达式的值。例如在 Ognl.jsp 中加入以下代码:
<hr />
<h3>% 的用途 </h3>
<p><s:url value="#foobar['foo1']" /></p>
<p><s:url value="%{#foobar['foo1']}" /></p>
清单 6 演示 % 用途的代码片段
刷新页面,结果如下所示:
清单 7 示例运行结果 2
“$” 有两个主要的用途
用于在国际化资源文件中,引用 OGNL 表达式,例子请参考《在 Struts 2.0 中国际化 (i18n) 您的应用程序》
在 Struts 2 配置文件中,引用 OGNL 表达式,如
<action name="AddPhoto" class="addPhoto">
<interceptor-ref name="fileUploadStack" />
<result type="redirect">ListPhotos.action?albumId=${albumId}</result>
</action>
清单 8 演示 $ 用途的代码片段
控制标签 [X1]
If elseif else append generator iterator merge sort subset
Append 元素与merge 元素拼合的方式不同:
Append :a.1 a.2 a.3 b.1 b.2 b.3 c.1 c.2
Merge : a.1 b.1 c.1 a.2 b.2 c.2 a.3 b.3 c.3
数据标签 DEMO
Action 在JSP 页面直接调用Action
Bean 创建一个javabean 实例 [X1]
Date 格式化输出一个日期( nice 指定是否输出其时差 )
Debug
I18n 指定国际化资源文件的basename
Include 用于在JSP 页面中包含其他的JSP 或servlet 资源
Param 设置一个参数,通常是用做bean 标签、url 标签的子标签
Push 将某个值放入ValueStack 的栈顶
Set 设置一个新变量,并可以将新变量放入指定的范围:applicatin,session
Text 输出国际化消息
url 生成一个url 地址
property 输出某个值,包括输出ValueStack 、Stack Context 、Action Context 中的值
UI 标签
都是基于主题和模板的 [X1]
不用尝试自己加载模板,开发者只要指定主题就够了,主题会负责去加载模板 [X2]
需要掌握的知识点:
1. 为struts2 标签指定theme 的方式(7 种)
2. Struts2 常用的主题及其特性 simple ( 不会有额外的布局功能) css_xhtml xhtml ( 默认的,非常方便,两列布局,输出检验错误提示,出处客户端校验提示)
主题是模板的组织形式,模板被包装在主题里面,;
设置主题的方法:
1. 通过设定特定 UI 标签上的 theme 属性来指定主题 ;
2. 设定特定 UI 标签外围的 Form 标签的 theme 属性
3. 取得 Page 会话范围的内以 theme 为名称的属性来确定主题;
4. 取得 Request 会话范围的内以 theme 为名称的属性来确定主题;
5. 取得 Session 会话范围的内以 theme 为名称的属性来确定主题;
6. 取得 application 会话范围的内以 theme 为名称的属性来确定主题;
7. 通过设置名为 struts.ui.theme 的常量(默认值是 xhtml )来确定默认主题,此常量可以在 struts.properties 文件或者 struts.xml 文件确定
Struts 可以选择自己的模板技术,通过修改 struts.ui.templateSuffix 常量的值就可以改变 struts2 默认的模板技术。
Ftl :(缺省) 基于 Freemaker 的模板技术;
Vm :基于 Velocity 的模板技术;
Jsp :基于 JSP 的模板技术
<action name=””>
<result>.</result>
</action>
<!— 浏览器 列出当前目录 -->
表单标签:
分两类: form 标签本身;单个表单元素的标签
Form 标签的行为不同于表单元素标签。Struts2 的表单元素标签都包含了非常多的属性,但有很多属性
完全是通用的。
所有表单标签处理类都继承了 UIBean 类, UIBean 包含了一些通用属性,这些通用属性分为了 3 类:
模板相关属性
Javascript 相关属性
通用属性
doubleselect doubleselect 02 [W1] 级联
Head 标签
生成一个隐藏域,生成的参数是随机的。
防止重复提交:
1. 进入表单页面时,系统会生成一个随机字符串,并将其放入 session ,并放入页面中的一个隐藏域
2. 提交请求时,系统会将 sessin 中的随机参数与隐藏域的随机参数进行对比,如果相同,即判断为有效请求,系统要清空 session 中的 ..
3. 如果刷新,隐藏域对应的请求参数没变,但 session 中随机字符串已经没了,此时隐藏域的与 session 的不 pi 配,判断为无效请求。
非表单标签:
Actionerror actionmessgae component fielderror
内建类型转换器:
boolean 和 Boolean :完成字符串与布尔值之间的转换
char 和 Character
int 和 Integer
long 和 Long
float 和 Float
double 和 Double
Date :完成字符串与日期类型之间的转换日期格式使用用户请求所在 Locale 的 SHORT 格式
数组:在默认情况下,数组元素是字符串,如果用户提供了自定义类型转换器,也可以是其他复合类型的数组。 [W1]
集合:在默认情况下,假定集合元素类型为 String ,并创建一个新的 ArrayList 封闭所有的字符串
对于数组的类型转换将按照数组元素的类型来单独转换每个元素,但对于其他的类型转换,如果转转换无法完成,系统将出现类型转换
基于OGNL 的类型转换:
指定集合对象的类型 DEMO
ActinName -converesion .properties 文件放到 Action 所在的目录下
通过局部类型转换文件指定如下 key-value 对
Element_users=lee.user (List 类型的做法 [W1] )
如果是 Map 类型的,则需要同时指定 Map 类型的 key 类型和 value 类型:
Key_<MapPropName>=<keyType>
Element_<MapPropName>=<valueType>
自定义类型转换: DEMO
1) 实现 TypeConverter 接口 ,意味着要完成类型转换的全部工作
2) 实现 TypeConverter 接口比较复杂,可继承 DefultTypeConver [W1]
3) 更简单的是继承 StrutsTypeConverter 上课实例 DEMO UserVoConverter.java
重写 convertFromString ( string 到自定义类型 疯狂JAVA 实例 DEMO
重写 convertToString ( 自定义类型到 string
注册类型转换器:
全局: 在类加载路径下指定 xwork-conversion.properties DEMO
自定义类型 = 转换器类
局部: 指定对特定的Action 的特定的属性使用指定的转换器 DEMO
局部类型的转换的文件放到Action 相同的路径下,文件名为AcitonName-conversion.properties
Action 属性名= 转换器类
# 指定user 属性需要使用lee.UserConverter 类来完成类型转换
user=lee.UserConverter
使用JDK1.5 的注释来注册类型转换器。
全局类型转换器是根据目标类来起作用的-- 只有你的Aciton 类里有指定类型的属性,
那么自定义类型转换器就会起作用。
局部类型转换器是根据指定Action 的指定属性来起作用的,-- 此类型转换器只对特定Acitn 类的特定属性起作用
struts2 的 ActionSupport 基类负责收集类型转换错误、输入检验错误,并将它们封闭成 FieldError 对象,添加到 ActionContext 中。
转换失败时,系统会跳到input Result ,因此需要配置name="input" 的result ;
struts 全局使用key 为Xwork.default.invalid.fieldvalue 的消息作为提示信息。
Xwork.default.invalid.fieldvalue ={0} 字段类型转换失败
需要对特定字段指定特别的提示信息,通过学习Action 的局部资源文件来实现,
invalid.fieldvalue.<propName>=<tipMsg>
在页面上显示错误提示:
1. 使用xhtml 主题的struts 2 标签
2. 使用<s:fieldError /> 来输出
错误提示的国际化
全局 在全局的国际化文件里添加key 为Xwork.default.invalid.fieldvalue ={0} 字段类型转换失败
局部 在局部的国际化文件里添加key 为invalid.fieldvalue.<propName>=<tipMsg>
处理集合类型的错误处理:
struts2 提供了一个名为 conversionError 的拦载器,这个拦载器被注册在默认的拦载器栈中。此拦载器负责将对应错误封闭成表单域错误( FieldError )
输入检验: DEMO
服务端检验: 防止非法数据进入程序,导致程序异常、底层数据库异常。服务器端校验是保证程序有效运行及数据完整的手段
1. 编写校验规则文件
a) 校验规则文件与Aciton 的类文件放在同一路径
b) 校验规则文件名 就是 Aciton 的类名-validatin .xml
2. 页面上使用 表单标签,会输出验 证错误 。或使用<s:fielderror /> 也可以输出
3. 错误提示国际化输出 <s:message key= />
客户端检验: 拒绝误操作输入提交到服务器处理,降低服务器负担, 异常 DEMO
1. 应该用<s:form ../> 生成表单
2. 为<s:form ../> 增加validate="true"
3. [W3] 如果希望国际化,应该把错误信息放到全局 国际化资源中。并用${getText("key")} 的方式来加载国际化消息
如果希望类型转换还有输入检验可以正常工作,记住你的Action 应该继承ActinSupport
转换失败时,系统会跳到input Result ,因此需要配置name="input" 的result ;