表现层数据是由用户输入的,用户输入则是非常复杂的,正常用户的偶然错误,还有Cracker(破坏者)的恶意输入,都可能导致系统出现非正常情况。例如,在如图4.2所示的输入页面中,我们希望用户输入crazyit.org,leegang模式的字符串,希望用户输入的字符串包含一个英文逗号(,)作为用户名和密码的分隔符,如果用户输入多于一个的英文逗号,或者没有输入英文逗号,都将引起系统异常——因为上面的类型转换器将无法正常分解出用户名和密码。

实际上,表现层数据涉及的两个处理:数据校验和类型转换是紧密相关的,只有当输入数据是有效数据时,系统才可以进行有效的类型转换——当然,有时候即使用户输入的数据能进行有效转换,但依然是非法数据(假设需要输入一个人的年龄,输入200则肯定是非法数据)。因此,可以进行有效的类型转换是基础,只有当数据完成了有效的类型转换后,下一步才去做数据校验。

Struts 2提供了一个名为conversionError的拦截器,这个拦截器被注册在默认的拦截器栈中。我们查看Struts 2框架的默认配置文件struts-default.xml,该文件中有如下配置片段:

...

input,back,cancel,browse

...

在上面的默认拦截器栈中包含了conversionError拦截器的引用,如果Struts 2的类型转换器执行类型转换时出现错误,该拦截器将负责将对应错误封装成表单域错误(FieldError),并将这些错误信息放入ActionContext中。

显然,conversionError拦截器实际上是AOP中的Throws处理(关于各种处理类型的定义和深入介绍,请参阅本书关于Spring的介绍)。Throws处理当系统抛出异常时启动,负责处理异常。通过这种方式,Struts 2的类型转换器中只完成类型转换逻辑,而无须关心异常处理逻辑。因此,我们看到上面的类型转换器无须进行任何异常处理逻辑。

图4.6显示了Struts 2类型转换中的错误处理流程。

图4.6只显示了类型转换器、conversionError拦截器和控制器之间的顺序图,并未完全刻画出系统中的其他成员。当conversionError拦截器对转换异常进行处理后,系统会跳转到名为input的逻辑视图。

图4.6Struts 2类型转换中的错误处理流程

为了让Struts 2框架处理类型转换的错误,以及使用后面的数据校验机制,系统的Action类都应该通过继承ActionSupport类来实现。ActionSupport类为完成类型转换错误处理,数据校验实现了许多基础工作。

1.处理类型转换错误

下面将以最简单的局部类型转换器为例,介绍如何处理类型转换错误。

我们重新改写系统的Action类,让系统的Action类继承Struts 2的ActionSupport类。修改后的Action类代码片段如下。

程序清单:codes\04\4.1\errorHandler\WEB-INF\src\org\crazyit\app\action\LoginAction.java

//为了正常使用系统的类型转换错误处理机制,让Action类继承ActionSupport类

public class LoginAction

extends ActionSupport

{

//该类包含一个User类型属性,该属性用于封装名为user的请求参数

private User user;

private String tip;

//省略该类的其他成分

...

}

为了让Struts 2类型转换的错误处理机制生效,包括下一节的输入校验生效,都必须让Action继承Struts 2的ActionSupport基类,因为Struts 2的ActionSupport负责收集类型转换错误、输入校验错误,并将它们封装成FieldError对象,添加到ActionContext中。

前面已经提到,当类型转换出现异常时,conversionError拦截器会处理该异常,然后转入名为input的逻辑视图,因此应该为该Action增加名为input的逻辑视图定义。修改后的struts.xml文件代码如下。

程序清单:codes\04\4.1\errorHandler\WEB-INF\src\struts.xml

/p>

"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"

"http://struts.apache.org/dtds/struts-2.1.7.dtd">

/input.jsp

/welcome.jsp

/welcome.jsp

.

上面的粗体字代码为input逻辑视图指定了物理视图资源:input.jsp。经过上面配置,如果用户输入不能成功转换成User对象,系统将转入input.jsp页面,等待用户再次输入。

前面已经讲述过,Struts 2会负责将转换错误封装成FieldError,并将其放在ActionContext中,这样就可以在对应视图中输出转换错误,在页面中使用标签即可输出类型转换错误信息。

在默认情况下,使用标签会输出形如Invalid field value for field xxx的错误提示信息,其中xxx是Action中属性名,也是该属性对应的请求参数的名。

对于中文环境而言,用户通常希望看到中文的提示信息,因此应该改变默认的提示信息。只需在应用的国际化资源文件中增加如下一行代码,即可改变默认的类型转换错误的提示信息。

#改变默认的类型转换失败后的提示信息

xwork.default.invalid.fieldvalue={0}字段类型转换失败!

因为上面的资源文件中包含了非西欧字符,因此必须使用native2ascii命令来处理该文件。

也就是说,Struts 2使用key为xwork.default.invalid.fieldvalue的消息作为标准的提示信息,并在input.jsp页面中增加如下代码:

改变了默认提示信息后,如果再次提交包含不能合理转换的请求参数,将看到如图4.7所示的页面。

图4.7类型转换错误的提示信息

提示:当我们使用Struts 2提供的表单标签来生成表单时,这些表单标签不仅可以为我们增加额外的布局功能,还可以自动输出类型转换失败的提示信息和输入校验失败的提示信息。

在某些时候,可能还需要对特定字段指定特别的提示信息,此时可通过Action的局部资源文件来实现,在文件中增加如下一项:

invalid.fieldvalue.=

将其中替换成需要进行类型转换的属性名(此处的propName可以支持OGNL表达式,例如user.birth代表Action里user属性的birth属性),替换成转换失败后的提示信息,上面的转换错误提示就会发挥作用了。

对于如图4.8所示的请求页面,其中包含了用户姓名、用户年龄和用户生日三个表单域,它们代表三个请求参数,这三个请求参数由Struts 2采用字符串、整数型和日期类型属性封装,因此必须涉及到类型转换!本应用的类型转换是基于OGNL表达式的类型转换。

图4.8输入用户信息的输入页面

处理上面请求的Action类代码如下。

程序清单:codes\04\4.1\errorHandler2\WEB-INF\src\org\crazyit\app\action\LoginAction.java

public class LoginAction extends ActionSupport

{

private User user;

//user属性的setter和getter方法

public void setUser(User user)

{

this.user = user;

}

public User getUser()

{

return user;

}

//没有execute方法,直接使用ActionSupport的execute方法

}

因为要改变birth属性的类型转换失败的提示信息,所以我们为该Action提供一个局部资源文件,该文件内只包含如下一行代码。

程序清单:codes\04\4.1\errorHandler2\WEB-INF\src\org\crazyit\app\action\LoginAction.properties

#改变上面的Action中user属性的birth属性类型转换后的提示信息

invalid.fieldvalue.user.birth=生日信息必须满足yyyy-MM-dd格式

该文件的文件名为LoginAction.properties(用native2ascii处理后新文件名为LoginAction_zh_CN. properties),将该文件放在与LoginAction.class相同的位置(例如WEB-INF\classes\org\crazyit\app\action路径下)。如果我们在如图4.8所示的输入页面中输入了不能成功进行类型转换的字符串,将看到如图4.9所示的页面。

在图4.9中可以看到,输入的年龄参数无法正常转换,生日参数也无法正常转换,其中“age字段无效”是全局的转换错误提示,由xwork.default.invalid.fieldvalue消息提供,后面的生日字段的转换错误提示则是单独指定的。

上面的转换错误信息是红色的,而不是黑色的,

仅仅是因为笔者增加了一个

标签,该标签可以导入xhtml主题所需要的一些CSS样式。

图4.9输出类型转换的错误提示

2.处理集合属性的转换错误

如果Action里包含一个集合属性,只要Struts 2能检测到集合里元素的类型(可以通过局部类型转换文件指定,也可通过泛型方式指定),类型转换器就可以正常起作用。当类型转换器在执行类型转换过程中出现异常时,系统的conversionError拦截器就会处理该异常,处理结束后返回名为input的逻辑视图。

假设有如下Action处理类,该处理类里包含一个List集合属性。

程序清单:codes\04\4.1\ListErrorHandler\WEB-INF\src\org\crazyit\app\action\LoginAction.java

//使用Struts 2的类型转换的错误机制,应该继承ActionSupport

public class LoginAction extends ActionSupport

{

private List users;

//users属性的setter和getter方法

public void setUsers(List users)

{

this.users = users;

}

public List getUsers()

{

return users;

}

}

对于上面的Action,该Action需要的users属性是一个List集合,我们有两种方式来传入请求参数:

Ø只传入一个users请求参数,该请求参数的值是字符串数组的形式;

Ø分别传入多个users[0]、users[1]…形式的请求参数,这种形式将会充分利用OGNL表达式类型转换机制。

对于第一种形式,因为只有一个请求参数,请求参数名为users,只要任何一个users请求参数不能成功转换成User对象,Struts 2都会提示users字段无效,如图4.10所示。

如果将三个请求参数的名字设为users[0]、users[1]…的形式,Struts 2将可以区分每个请求参数,从而显示更友好的转换错误提示。例如,我们将表单页的代码改为如下。

程序清单:codes\04\4.1\ListErrorHandler\ognlInput.jsp

图4.10集合属性类型转换失败

label="第%{#stat.index}个用户信息"/>

上面的页面代码我们使用了迭代器标签来指定三个表单域的name,三个表单域的name将分别是users[0]、users[1]、users[2],在这种情况下如果任一个表单域类型转换失败,将看到如图4.11所示的页面。

图4.11集合属性类型转换失败

java类型转换异常处理_类型转换中的错误处理相关推荐

  1. 下列叙述中正确的是 java语言_1. 下列关于JAVA语言特点的叙述中,错误的是[   ] A、Java是面向过程的编程语言...

    1. 下列关于JAVA语言特点的叙述中,错误的是[  ]A.Java是面向过程的编程语言   B.Java支持分布式计算C.Java是跨平台的编程语言   &... 1. 下列关于JAVA语言 ...

  2. java全局异常处理_详解Spring全局异常处理的三种方式

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作 ...

  3. java spring异常处理_Spring项目中优雅的异常处理

    前言 如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Co ...

  4. Java SSH 集成框架开发中的错误解决

    记录一些Java 三大框架集成项目开发过程中发生的一些错误的解决,都是实际经验,记一下备忘.这些错误可以说比较诡异:有的目前尚未分析清楚原因,资料上也未说过. 一 找不到项目报404 一次在开发调试过 ...

  5. java美元兑换_代码中的美元$

    这个题目其实有点标题党了,其实本篇文章主要内容应该是说"代码中的美元符号(dollar sign)".想总结一下我所看到的美元符号在代码中的起到的作用,当然了并不是说它作为格式化字 ...

  6. java spring异常处理_【异常处理】Spring项目异常如何做异常处理

    类似SpringMVC项目的异常处理可以这样做: 整个项目创建全局的: 1.一个自定义异常如OneException和错误码,统一封装所有异常. 2.一个返回实体类ResponseEntity,包含返 ...

  7. java 初始化系统参数_系统中参数的初始化 参数在系统中配置

    1.我们来看这个需求,例如:我们上传图片.上传附件 需要放在服务器上的一个目录上,该目录在不同的操作系统下是不同的.因为我们在写java代码的时候就不能写死. 这个时候我们就要用到系统参数.在界面上自 ...

  8. java 正则表达式 反向_正则表达式中的数量表示符、反向引用、零宽断言、以及java中的用法...

    在表示数量时,如果一个正则表达式X,后面没有加表示数量的符号,那就默认出现一次.如果指定需要出现n次,那就用{n},例如a{n},就是匹配a出现n次的.a{n,}表示a出现至少n次的,而这个时候就会默 ...

  9. 下列关于java语言特性,下列关于Java 语言特点的叙述中,错误的是()。

    鳃是鱼类的呼吸器官,硬骨鱼类共有______对全鳃,而软骨鱼类共有______个半鳃. 男工人数是女工人数的25,男.女工人数的比是______. 颅内手术后,头部翻转过猛可引起A.脑疝B.休克C.脑 ...

  10. java cpu分配_容器中的Java:资源分配准则

    短短几年内,容器就改变了软件行业的面貌.也许您已经到了在容器中运行Java的地步.那很棒!不幸的是,关于容器化Java应用程序的CPU和内存使用率,还有一些事情要注意,我将在下面概述. 本文假定总体上 ...

最新文章

  1. NodeJS:将指定文件夹内所有文件重命名为英文
  2. 实战SSM_O2O商铺_34【商品】商品编辑之Controller层的实现
  3. 关于 IE 模态对话框的两个问题
  4. PHP实现动态获取函数参数的方法
  5. 揭开《钢铁侠》AI管家贾维斯神秘面纱的扛鼎之作!
  6. 全球及中国城市规划行业十四五建设方向与运营动态分析报告2022版
  7. 连接池原理解读,各个连接池对比
  8. 云计算激荡十五年:亚马逊云科技的探路者精神
  9. 有对象的程序猿都是怎么写代码的
  10. 深度学习:行为识别综述
  11. lighttpd服务器搭建教程
  12. redis设计秒杀活动图解
  13. Go语言核心之美 1.4-包和文件
  14. 挑战程序设计竞赛(第2版)pdf
  15. 烧录软件BlueSuite.WIN.3.3 Installer_3.3.14.1471
  16. mysql动态规划_关于动态规划的描述,不正确的是( )
  17. 查看网络交换机光口的光功率
  18. 中文汉字和常见英文数字等的unicode编码范围
  19. 苹果a10处理器_苹果新的2020Pad升级了处理器仅此而已
  20. android 拍照使用fileprovider遇到的坑

热门文章

  1. python与财务报表分析_《财务报表分析》第八章 企业财务综合分析与业绩评价课后练习...
  2. cad画流程图的插件_CAD高手教您画工艺流程图设计一些列图
  3. 支付系统---银行卡收单业务
  4. css span img,css设置span和img垂直居中(设置line-height失效)
  5. iGoogle背后的思考
  6. 记录一次组装台式机设置U盘启动
  7. 《手把手陪您学Python》24——集合
  8. 将Excel列转为字符串存到数据库表中
  9. CSDN调整图片大小
  10. 电商项目5:商品模块