Struts2干货笔记——第二天

目录

1. Struts2提供了三种数据封装的方式
2. 封装数据到Collection和Map
3. Struts2类型转换器
4. 类型转换器中的错误处理
5. 请求参数验证
6. 对action中的指定方法进行校验
Struts2提供了三种数据封装的方式
1. 属性驱动
  • Action本身作为model对象,通过setter封装
    页面:
    用户名 <input type="text" name="username" />

    Action :
    public class RegistAction extends ActionSupport {
    private String username;
    public void setUsername(String username) {
    this.username = username;
    }
    }

  • 创建独立的model对象,页面通过ognl表达式封装
    页面:
    用户名 <input type="text" name="user.username" />
    // 基于OGNL表达式的写法
    Action:
    public class RegistAction2 extends ActionSupport {
    private User user;
    public void setUser(User user) {
    this.user = user;
    }

       public User getUser() {
           return user;
       }
     }
    
2. 模型驱动(主流)
  • 使用ModelDriven接口,对请求参数进行封装
    页面:
    用户名 <input type="text" name="username" />

    Action :
    public class RegistAction3 extends ActionSupport implements ModelDriven<User> {
    private User user = new User(); // 必须手动实例化
    public User getModel() {
    return user;
    }
    }

封装数据到Collection和Map

  1. 封装数据到Collection,常见于需要快速录入批量数据的场景
    页面:
    产品名称 <input type="text" name="products[0].name" />

    Action :
    public class ProductAction extends ActionSupport {
    private List<Product> products;

         public List<Product> getProducts() {
             return products;
         }
    
         public void setProducts(List<Product> products) {
             this.products = products;
         }
     }
    

页面:
产品名称 <input type="text" name="map['one'].name" />
-- one是map的键值
Action :
public class ProductAction2 extends ActionSupport {
private Map<String, Product> map;

        public Map<String, Product> getMap() {
            return map;
        }

        public void setMap(Map<String, Product> map) {
            this.map = map;
        }
    }   

Struts2类型转换器

当我们发送一个HTTP请求时,请求的内容都以字符串的形式发送给服务器,所以需要转换成Action里定义的类型,例如,如果你的Action类中有一个integer属性,你不需要执行任何操作,Struts会自动将请求参数转换为integer属性。对于大部分常用类型,无需创建转换器,Struts2内置了很多常见数据类型的转换器。

  • boolean 和 Boolean
  • char和 Character
  • int 和 Integer
  • long 和 Long
  • float 和 Float
  • double 和 Double
  • Date 可以接收 yyyy-MM-dd格式字符串
  • 数组 可以将多个同名参数,转换到数组中
  • 集合 支持将数据保存到 List 或者 Map 集合

struts2中的类型转换器根接口是:com.opensymphony.xwork2.conversion.TypeConverter。

自定义类型转换器

Date类型的属性可以接收格式为2000-02-20的请求参数,但是如果要接收格式为20000220的请求参数,就必须要自定义类型转换器,否则struts2无法自动完成类型转换。

步骤:

  1. 创建一个类实现TypeConverter接口.
  2. 重写接口中方法,实现类型转换操作.
  3. 注册类型转换器.

** 创建自定义类型转换器的方法 **

  1. 实现TypeConverter,重写方法
    public Object convertValue(Map<String, Object> context, Object target,
    Member member, String propertyName, Object value, Class toType);
  2. 继承 DefaultTypeConverter类
    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
    return convertValue(value, toType);
    }
  3. 继承DefaultTypeConverter类的一个子类StrutsTypeConverter(推荐)
    public abstract Object convertFromString(Map context, String[] values, Class toClass);
    public abstract String convertToString(Map context, Object o);

** 注册一个自定义类型转换器 **

  1. 局部--针对于action
    配置文件所在位置以及名称: 在Action类所在包 创建 Action类名-conversion.properties ,
    配置文件书写: 格式 : 属性名称=类型转换器的全类名
  2. 局部--针对于model
    配置文件所在位置以及名称: 在model类所在包 创建 model类名-conversion.properties ,
    配置文件书写: 格式 : 属性名称=类型转换器的全类名
  3. 全局
    配置文件所在位置以及名称:在src下创建一个xwork-conversion.properties
    配置文件书写: 格式: 要转换的类型全名=类型转换器的全类名


    举例.PNG

类型转换器中的错误处理

我们希望用户输入abc,def模式的字符串,输入的字符串包含一个英文逗号作为用户名和密码的分隔符,如果用户输入了多个英文逗号,或者没有输入英文逗号,都将引起系统异常,因为上面的类型转换器将无法正常解出用户名和密码,实际上,表现层数据涉及两个处理:数据校验和类型转换是紧密相关的,只有当输入数据时有效数据时,系统才可以进行有效的类型转换——当然,有时候即使用户输入的数据能进行有效转换,但依然是非法数据(假设需要输入一个人的年龄,输入200则是非法数据)。因此,可以进行有效的类型转换时基础,只有当数据完成了有效的类型转换后,下一步才去做数据校验。

Struts2提供了一个名为conversion-Error的拦截器,这个拦截器被注册在默认的拦截器栈中,我们查看Struts2框架的默认配置文件:struts-default.xml文件,
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

通过分析拦截器作用,得知当类型转换出错时,自动跳转input视图 ,在input视图页面中 <s:fieldError/> 显示错误信息
在Action所在包中,创建 ActionName.properties,在局部资源文件中配置提示信息 : invalid.fieldvalue.属性名= 错误信息

请求参数验证

两种方式:

  • 手动校验
  • 配置校验(xml)

** 1. 手动校验(了解) **

  • 继承ActionSupport,重写validate()方法,在该方法中完成验证,validate()方法在其他的业务方法之前执行
  • 验证出错后转向的页面
    struts.xml配置<result name="input">/validate/login.jsp</result>
  • 什么时候表示验证出错?
    this.addFieldError("a","错误信息");方法指向的一个集合
    当集合不为空时,转向错误页面。
    在jsp页面中使用
    <s:fielderror> 展示所有错误信息
    <s:fielderror fieldName="">展示特定名称的错误信息

** 2. 配置校验(重点) **
要求:action类必须继承自ActionSupport
配置文件:

  • 位置:xml文件要与action类在同一个包下
  • 名称:action类名-validation.xml
  • 约束: xwork-core-2.3.7.jar 中 xwork-validator-1.0.3.dtd 下
    <!DOCTYPE validators PUBLIC
    "-//Apache Struts//XWork Validator 1.0.3//EN"
    "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
  • 写法:
    1)根元素<validators>
    2)子元素<field name="属性名称"></field>,name为页面被验证的表单字段的名称
    3)<field>的子元素<field-validator type="校验器"> 这个是指定校验器
    校验器有哪些?
    在xwork-core-2.3.7.jar 中 /com/opensymphony/xwork2/validator/validators/default.xml下
    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
    <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
    <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
    <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
    4)<field-validator>的子元素<message>错误信息</message>
    5)<field-validator>子元素的<param name="">值</param>用于指定校验器中的参数

** 系统提供的校验器:**

  • required (必填校验器,要求被校验的属性值不能为null)
  • requiredstring (必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默* 认情况下会对字符串去前后空格)
  • stringlength (字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验
  • field之前是否去除字符串前后的空格)
  • regex (正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)
  • int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)
  • double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)
  • fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)
  • email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)
  • url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)
  • date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)

required 必填校验器

<field-validator type="required">
<message>性别不能为空!</message>
</field-validator>
```

requiredstring  必填字符串校验器
```
<field-validator type="requiredstring">
       <param name="trim">true</param>
       <message>用户名不能为空!</message>
</field-validator>
```
stringlength:字符串长度校验器
```
<field-validator type="stringlength">
    <param name="maxLength">10</param>
    <param name="minLength">2</param>
    <param name="trim">true</param>
    <message><![CDATA[产品名称应在2-10个字符之间]]></message>
</field-validator>
```
int:整数校验器
```
<field-validator type="int">
    <param name="min">1</param>
    <param name="max">150</param>
    <message>年龄必须在1-150之间</message>
</field-validator>
```
date: 日期校验器
```
<field-validator type="date">
    <param name="min">1900-01-01</param>
    <param name="max">2050-02-21</param>
    <message>生日必须在${min}到${max}之间</message>
</field-validator>

url:  网络路径校验器
<field-validator type="url">
    <message>传智播客的主页地址必须是一个有效网址</message>
</field-validator>
```
email:邮件地址校验器
```
<field-validator type="email">
    <message>电子邮件地址无效</message>
</field-validator>
```
regex:正则表达式校验器
```
<field-validator type="regex">
     <param name="regexExpression"><![CDATA[^13\d{9}$]]></param>
     <message>手机号格式不正确!</message>
</field-validator>
```
fieldexpression : 字段表达式校验
```
<field-validator type="fieldexpression">
       <param name="expression"><![CDATA[(password==repassword)]]></param>
       <message>两次密码输入不一致</message>
</field-validator>
```

**对action中的指定方法进行校验**
当校验文件的取名为ActionClassName-validation.xml时,会对action中的所有处理方法实施输入验证,如果只需要对action中的某个action方法校验,那么,校验文件的取名应该为ActionClassName-ActionName-validation.xml,**其中ActionName为Struts.xml中action的名称**。例如:
```
<action name="user_*" class="com.java.action.UserAction" method="{1}" >
        <result name="success">/WEB-INF/page/message.jsp</result>
        <result name="input">/WEB-INF/page/addUser.jsp</result>
</action>
```
在UserAction中有两个处理方法:
public String add() throws Exception{}
public String update() throws Exception{}
要对add()方法实施验证,校验文件取名为:UserAction-user_add-validation.xml
要对update()方法实施验证,校验文件取名为:UserAction-user_update-validation.xml
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 概述 Struts就是基于mvc模式的框架!(struts其实也是servlet封装,提高开发效率!) Strut...
    奋斗的老王阅读 2,929评论 0 51
  • 果然,只有闲的人才会想太多。 不,应该是闲的时候会为浪费时间而焦急,难过,自责。所以,多种负面的情绪积杂在一起,整...
    AliveorDead阅读 193评论 0 0
  • 选择拍摄室内婚纱照有什么技巧 遂宁婚纱摄影价格最低多少钱? 选择拍摄室内韩式婚纱照有什么技巧 拍室内婚纱照,一样拍...
    遂宁金公主摄影客服阅读 470评论 0 0