7.类型转换、消息处理与国际化
2016-12-03 11:20
183 查看
前边我们说过了 Http协议 有两个缺陷一个是无状态、一个是纯文本。
纯文本也就是说Http请求中的内容都是以字符串的形式发送的。
但是Java又是一个强类型语言,所以将一个字符串转换成Java中的数据类型这一重任就落在了Struts2的肩膀上。
类型转换最常见的可能就是将将10/29/2015转换为一个date类型等。
关于类型转换我们要做的主要有两件事:
类型转换失败后的处理。
特殊类型的自定义类型转换器。
若 Action 类没有实现 ValidationAware 接口: Struts 在遇到类型转换错误时仍会继续调用其 Action 方法, 就好像什么都没发生一样.
若 Action 类实现 ValidationAware 接口:Struts 在遇到类型转换错误时将不会继续调用其 Action 方法:
Struts 将检查相关 action 元素的声明是否包含着一个 name=input 的 result.
如果有, Struts 将把控制权转交给那个 result 元素;
若没有 input 结果, Struts 将抛出一个异常
实现
类型转换出错时如何处理
如果我们输入错误的数字,想转换为年龄;当我们的 result name="input" 的时候,会返回到这个结果页面。
但是对于这种错误的提示,我们需要处理
类型转换错误消息的定制
作为默认的 default 拦截器的一员, ConversionError 拦截器负责添加与类型转换有关的出错消息(前提: Action 类必须实现了 ValidationAware 接口)和保存各请求参数的原始值.
若字段标签使用的不是 simple 主题, 则非法输入字段将导致一条有着如上图格式的出错消息。
覆盖默认的出错消息
在对应的
在属性文件中添加如下键值对: invalid.fieldvalue.fieldName=Customer Message
定制出错消息的样式:
每一条出错消息都被打包在一个 HTML span 元素里, 可以通过覆盖其行标为 errorMessage 的那个 css 样式来改变出错消息的格式.
显示错误消息: 如果是 simple 主题, 可以通过
但是对于这种错误消息的格式我们是可以修改的,修改其默认的 freemark 模板
在struts2-core-2.3.15.3.jar 的 /template/simple/fielderror.ftl,这是 struts2 默认自带的错误消息模板,我们在 src 路径下建立相同的包和模板,并且修改里面的 html 标签。删除文件中错误消息的 的 ul、li、span便签
![删除的模板
自定义类型转换器必须实现
扩展 StrutsTypeConverter 类
在大多数类型转换器里, 需要提供从 String 类型到非 String 类型和与此相反的转换功能
在 StrutsTypeConverter 中有两个抽象方法:
配置自定义的类型转换器
在应用程序里使用一个自定义的类型转换器之前, 必须先对它进行配置. 这种配置既可以基于字段, 也可以基于类型
基于字段类型转换配置-局部转换器
可以为某个 Model(该 Model 类也可能是 Action) 的各个属性分别配置一个自定义的转换器.
创建一个属性文件: ModelClassName-conversion.properties, 该文件需和相对应的 Model(Model有可能是一个Action) 类放在同一个目录下
fieldName=Converter全类名,例如:
基于类型-全局转换器
在资源目录下,src 或者 其他的 resources 创建
在 xwork-conversion.properties 文件里把每一个需要进行类型转换的类与一个类型转换器关联起来
若类型转换失败,给出自定义的信息。
类型转换与复杂属性配合使用
form 标签的 name 属性可以被映射到一个属性的属性.
集合协同
类型转换与 Collection 配合使用
在程序设计领域, 把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化.
与国际化对应的是本地化, 指让一个具备国际化支持的应用程序支持某个特定的地区
Struts2 国际化是建立在 Java 国际化基础上的:
为不同国家/语言提供对应的消息资源文件
Struts2 框架会根据请求中包含的
Locale 加载对应的资源文件
通过程序代码取得该资源文件中
指定 key 对应的消息
默认拦截器栈中有一个
当i18n拦截器被调用时,他会先去查找request_locale这个请求参数,它会根据干参数来创建一个Locale对象。并将Locale对象放入进session域中。之后在加载国际化资源文件时就根据刚刚创建的Locale对象
当i18n拦截的请求中没有request_locale这个参数,
它会先去session中获取Locale对象,如果session中,则直接使用该对象
如果session中没有,则会根据用户浏览器信息或本地服务器的信息去创建一个Locale对象并使用。
配置国际化资源文件
Action 范围资源文件:
在Action类文件所在的路径建立名为
包范围资源文件:
在包的根路径下建立文件名为
注意:包范围资源文件的 baseName 就是package,不是Action所在的包名。
全局资源文件
命名方式:
临时指定资源文件:
总结:
国际化资源文件加载的顺序如何呢 ?
离当前 Action 较近的将被优先加载.
假设我们在某个
(1)加载和 ChildAction 的类文件在同一个包下的系列资源文件 ChildAction.properties
(2)加载 ChildAction 实现的接口 IChild,且和 IChildn 在同一个包下 IChild.properties 系列资源文件。
(3)加载 ChildAction 父类 Parent,且和 Parent 在同一个包下的 baseName 为 Parent.properties 系列资源文件。
(4) 若 ChildAction 实现 ModelDriven 接口,则对于getModel()方法返回的model 对象,重新执行第(1)步操作。
(5) 查找当前包下 package.properties 系列资源文件。
(6) 沿着当前包上溯,直到最顶层包来查找 package.properties 的系列资源文件。
(7) 查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。
(8) 直接输出该key的字符串值。
Action 范围国际化
package 范围国际化
全局的国际化
首先需要去 struts.xml 中指定baseName
在这还需要讲到一种方式:在页面国际化资源
如果我们在资源路径下建立好了 国际化资源,但是没有在 struts.xml 中配置 baseName
我们可以使用
访问国际化消息
JSP 页面访问国际化消息:
不带占位符:
表单元素的 label 属性:可替换为 key 或使用 getText() 方法,并对其进行强制 OGNL 解析,使用%{}
带占位符:
在
Struts2 直接在国际化消息资源文件中通过 “${}” 使用表达式,该表达式将从值栈中获取对应的属性值(对象栈 和 Map 栈)
Action 访问国际化消息:
若 Action 类继承了 ActionSupport ,则可调用 TextProvider 接口的 getText 方法。
利用超链接实现动态加载国际化资源文件
Struts2 使用 i18n 拦截器 处理国际化,并且将其注册在默认的拦截器中
i18n拦截器在执行Action方法前,自动查找请求中一个名为
如果该参数存在,拦截器就将其作为参数,转换成Locale对象,并将其设为用户默认的
若
若 session 中的 WW_TRANS_I18N_LOCALE 的属性值为空,则从 ActionContext 中获取 Locale 对象。
纯文本也就是说Http请求中的内容都是以字符串的形式发送的。
但是Java又是一个强类型语言,所以将一个字符串转换成Java中的数据类型这一重任就落在了Struts2的肩膀上。
类型转换最常见的可能就是将将10/29/2015转换为一个date类型等。
关于类型转换我们要做的主要有两件事:
类型转换失败后的处理。
特殊类型的自定义类型转换器。
类型转换失败消息处理
类型转换失败:若 Action 类没有实现 ValidationAware 接口: Struts 在遇到类型转换错误时仍会继续调用其 Action 方法, 就好像什么都没发生一样.
若 Action 类实现 ValidationAware 接口:Struts 在遇到类型转换错误时将不会继续调用其 Action 方法:
Struts 将检查相关 action 元素的声明是否包含着一个 name=input 的 result.
如果有, Struts 将把控制权转交给那个 result 元素;
若没有 input 结果, Struts 将抛出一个异常
实现
ValidationAware接口,在之前的文章中我们提到,我们可以继承
com.opensymphony.xwork2.ActionSupport类的形式来实现
ValidationAware接口, 在ActionSupport 中已经帮我们实现好了
类型转换出错时如何处理
如果我们输入错误的数字,想转换为年龄;当我们的 result name="input" 的时候,会返回到这个结果页面。
但是对于这种错误的提示,我们需要处理
类型转换错误消息的定制
作为默认的 default 拦截器的一员, ConversionError 拦截器负责添加与类型转换有关的出错消息(前提: Action 类必须实现了 ValidationAware 接口)和保存各请求参数的原始值.
若字段标签使用的不是 simple 主题, 则非法输入字段将导致一条有着如上图格式的出错消息。
覆盖默认的出错消息
在对应的
Action类所在的包中新建
ActionClassName.properties文件, ClassName 即为包含着输入字段的 Action 类的类名
在属性文件中添加如下键值对: invalid.fieldvalue.fieldName=Customer Message
# EmployeeAction.properties invalid.fieldvalue.age=年龄格式不正确,请重新输入!
定制出错消息的样式:
每一条出错消息都被打包在一个 HTML span 元素里, 可以通过覆盖其行标为 errorMessage 的那个 css 样式来改变出错消息的格式.
显示错误消息: 如果是 simple 主题, 可以通过
<s:fielderror fieldName=“filedname”></s:fielderror>标签显示错误消息
<s:form action="emp_update" theme="simple"> <s:hidden name="id"></s:hidden> 姓名:<s:textfield name="name"></s:textfield> <br> 年龄:<s:textfield name="age" ></s:textfield> <!-- 通过标签获取错误消息 --> <span style="color:red"><s:fielderror fieldName="age"></s:fielderror></span><br> 部门: <s:textfield name="dept"></s:textfield><br> 职务:<s:textfield name="role"></s:textfield><br> <s:submit value="修改"></s:submit> </s:form>
但是对于这种错误消息的格式我们是可以修改的,修改其默认的 freemark 模板
在struts2-core-2.3.15.3.jar 的 /template/simple/fielderror.ftl,这是 struts2 默认自带的错误消息模板,我们在 src 路径下建立相同的包和模板,并且修改里面的 html 标签。删除文件中错误消息的 的 ul、li、span便签
![删除的模板
自定义类型转换器
定制类型转换器自定义类型转换器必须实现
ongl.TypeConverter接口或对这个接口的某种具体实现做扩展
扩展 StrutsTypeConverter 类
在大多数类型转换器里, 需要提供从 String 类型到非 String 类型和与此相反的转换功能
在 StrutsTypeConverter 中有两个抽象方法:
配置自定义的类型转换器
在应用程序里使用一个自定义的类型转换器之前, 必须先对它进行配置. 这种配置既可以基于字段, 也可以基于类型
基于字段类型转换配置-局部转换器
可以为某个 Model(该 Model 类也可能是 Action) 的各个属性分别配置一个自定义的转换器.
创建一个属性文件: ModelClassName-conversion.properties, 该文件需和相对应的 Model(Model有可能是一个Action) 类放在同一个目录下
fieldName=Converter全类名,例如:
birth=org.pan.struts2.conver.DateConverter
基于类型-全局转换器
在资源目录下,src 或者 其他的 resources 创建
xwork-conversion.properties文件
在 xwork-conversion.properties 文件里把每一个需要进行类型转换的类与一个类型转换器关联起来
java.util.Date=org.pan.struts2.conver.DateConverter
若类型转换失败,给出自定义的信息。
复杂属性,集合协同工作
复杂属性类型转换与复杂属性配合使用
form 标签的 name 属性可以被映射到一个属性的属性.
<s:form action="user_add"> <s:textfield name="user.name" label="姓名"></s:textfield> <s:textfield name="user.gender" label="性别"></s:textfield> <s:textfield name="user.address" label="地址"></s:textfield> <s:textfield name="user.mgr.name" label="经理名称"></s:textfield> <s:textfield name="user.mgr.birth" label="经理生日"></s:textfield> <s:submit value="添加"></s:submit> </s:form>
集合协同
类型转换与 Collection 配合使用
国际化
概述在程序设计领域, 把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化.
与国际化对应的是本地化, 指让一个具备国际化支持的应用程序支持某个特定的地区
Struts2 国际化是建立在 Java 国际化基础上的:
为不同国家/语言提供对应的消息资源文件
Struts2 框架会根据请求中包含的
Locale 加载对应的资源文件
通过程序代码取得该资源文件中
指定 key 对应的消息
默认拦截器栈中有一个
i18n拦截器,这个拦截器用来设置当前
Locale信息
当i18n拦截器被调用时,他会先去查找request_locale这个请求参数,它会根据干参数来创建一个Locale对象。并将Locale对象放入进session域中。之后在加载国际化资源文件时就根据刚刚创建的Locale对象
当i18n拦截的请求中没有request_locale这个参数,
它会先去session中获取Locale对象,如果session中,则直接使用该对象
如果session中没有,则会根据用户浏览器信息或本地服务器的信息去创建一个Locale对象并使用。
配置国际化资源文件
Action 范围资源文件:
在Action类文件所在的路径建立名为
ActionName_language_country.properties的文件
包范围资源文件:
在包的根路径下建立文件名为
package_language_country.properties的属性文件,一旦建立,处于该包下的所有 Action 都可以访问该资源文件。
注意:包范围资源文件的 baseName 就是package,不是Action所在的包名。
全局资源文件
命名方式:
basename_language_country.properties
struts.xml
<constant name="struts.custom.i18n.resources" value="baseName"/>
<!-- 配置国际化资源 --> <constant name="struts.custom.i18n.resources" value="i18n"/>
临时指定资源文件:
<s:i18n.../>标签的
name属性指定临时的国际化资源文件
总结:
国际化资源文件加载的顺序如何呢 ?
离当前 Action 较近的将被优先加载.
假设我们在某个
ChildAction中调用了
getText("username"):
(1)加载和 ChildAction 的类文件在同一个包下的系列资源文件 ChildAction.properties
(2)加载 ChildAction 实现的接口 IChild,且和 IChildn 在同一个包下 IChild.properties 系列资源文件。
(3)加载 ChildAction 父类 Parent,且和 Parent 在同一个包下的 baseName 为 Parent.properties 系列资源文件。
(4) 若 ChildAction 实现 ModelDriven 接口,则对于getModel()方法返回的model 对象,重新执行第(1)步操作。
(5) 查找当前包下 package.properties 系列资源文件。
(6) 沿着当前包上溯,直到最顶层包来查找 package.properties 的系列资源文件。
(7) 查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。
(8) 直接输出该key的字符串值。
Action 范围国际化
package 范围国际化
全局的国际化
首先需要去 struts.xml 中指定baseName
<!-- 指定国际化 baseName, 以便于建立全局的国际化资源文件 --> <constant name="struts.custom.i18n.resources" value="myI18n"></constant>
在这还需要讲到一种方式:在页面国际化资源
如果我们在资源路径下建立好了 国际化资源,但是没有在 struts.xml 中配置 baseName
我们可以使用
<s:i18n name="baseName"> 标签来获取
<!-- 如果是配置了页面国际化资源文件, 那么国际的内容只能在i18n标签中使用,一旦离开i18n标签则不能使用 --> <s:i18n name="myI18n"> <s:text name="username"></s:text> <s:form> <s:textfield name="username" key="username"></s:textfield> <s:password name="password" key="password"></s:password> <s:submit key="submit"></s:submit> </s:form> </s:i18n>
访问国际化消息
JSP 页面访问国际化消息:
不带占位符:
<s:text name="key"/>
表单元素的 label 属性:可替换为 key 或使用 getText() 方法,并对其进行强制 OGNL 解析,使用%{}
带占位符:
在
Struts2 直接在国际化消息资源文件中通过 “${}” 使用表达式,该表达式将从值栈中获取对应的属性值(对象栈 和 Map 栈)
Action 访问国际化消息:
若 Action 类继承了 ActionSupport ,则可调用 TextProvider 接口的 getText 方法。
利用超链接实现动态加载国际化资源文件
Struts2 使用 i18n 拦截器 处理国际化,并且将其注册在默认的拦截器中
i18n拦截器在执行Action方法前,自动查找请求中一个名为
request_locale 的参数。
如果该参数存在,拦截器就将其作为参数,转换成Locale对象,并将其设为用户默认的
Locale(代表国家/语言环境)。并把其设置为 session 的 WW_TRANS_I18N_LOCALE 属性
若
request 没有名为request_locale 的参数,则 i18n 拦截器会从 Session 中获取 WW_TRANS_I18N_LOCALE 的属性值,若该值不为空,则将该属性值设置为浏览者的默认Locale
若 session 中的 WW_TRANS_I18N_LOCALE 的属性值为空,则从 ActionContext 中获取 Locale 对象。
<!-- 必須是 struts 請求,使得 i18 拦截器工作 --> <a href="userLogin.action?request_locale=en_US">English</a> <a href="userLogin.action?request_locale=zh_CN">中文</a>
相关文章推荐
- 从windows到linux的转换(1):信号与消息以及SIGPIPE 的处理
- 无法将类型“ASP.login_aspx”转换为“System.Web.UI.WebControls.Login” 错误处理
- Android 图像处理(类型转换,比例缩放,倒影,圆角)
- 日期类型的处理及转换
- vs2010自定义消息 无法类型转换的问题
- 异常信息:CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88,这种状态已持续60秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作.这种情况通常会影响到
- gridview导出excel文件且把数字类型的列转换成字符导出(防止处理成科学计数法)
- CLR 无法从 COM 上下文 0x1a2740 转换为 COM 上下文 0x1a28b0,这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作
- 异常信息:CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88,这种状态已持续60秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作.这种情况通常会影响到
- biztalk中使用.net class类型的消息(三) -- net class类型消息转换为xml消息的示例
- Java日期类型的转换处理
- Java日期类型的转换处理
- BOM 创建同步(消息类型和处理代码)
- JAVA图片处理--缩放,切割,类型转换
- Java日期类型的转换处理
- sql server 字符串处理和数据类型转换几点体会
- 无法将类型“string”隐式转换为“int”的处理办法
- 关于float double的数据类型的细节,在处理转换问题的时候非常有用
- struts2系列学习笔记(8)---------------类型转换的错误处理
- struts1 处理日期类型转换