• Java实战之01Struts203属性封装、类型转换、数据验证


    九、封装请求正文到对象中

    1、静态参数封装

    struts.xml配置文件中,给动作类注入值。调用的是setter方法。

    原因:是由一个staticParams的拦截器完成注入的。

    2、动态参数封装:开发时用到的

    通过用户的表单封装请求正文参数。

    2.1、动作类作为实体模型

    实体模型:Entity,对应数据库中表的记录(注意类对应的是表结构,而对象对应的是一条记录)

     1 public class Demo1Action extends ActionSupport {
     2 
     3     private String name;
     4     private int age;
     5         
     6     public String demo1(){
     7         System.out.println(name);
     8         System.out.println(age);
     9         return SUCCESS;
    10     }
    11 
    12     public String getName() {
    13         return name;
    14     }
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18     public int getAge() {
    19         return age;
    20     }
    21     public void setAge(int age) {
    22         this.age = age;
    23     }
    24 }
    1 <!-- 动态参数封装:使用表单提交数据,第一种方式 -->
    2         <action name="action2" class="cn.itcast.web.action.Demo2Action" method="demo2">
    3             <result name="success">/success.jsp</result>
    4         </action>
    1 <form action="${pageContext.request.contextPath}/action2" method="POST">
    2      用户名:<input type="text" name="name"/><br/>
    3      年龄:<input type="text" name="age"><br/>
    4      <input type="submit" value="提交"/>
    5 </form>

    原因:是由params拦截器完成的。

    2.2、动作类和实体模型分开

    问题:

    由于我们没有初始化user对象,默认为null,一调用setUser方法,就空指针异常了。但是框架却封装进去值了。

    原因:

    通过执行过程:

     1 public class Demo3Action extends ActionSupport {
     2 
     3     private User user = new User();
     4     
     5     public String demo3(){
     6         System.out.println(user.getName());
     7         System.out.println(user.getAge());
     8         return SUCCESS;
     9     }
    10 
    11     public User getUser() {
    12         System.out.println("getUser");
    13         return user;
    14     }
    15     public void setUser(User user) {
    16         System.out.println("setUser");
    17         this.user = user;
    18     }    
    19 }

    2.3、模型驱动:建立动作类和模型分开的前提下(开发中采用的方式)

    此处的学习目标:目前先记住怎么写,要想理解,必须等讲完OGNL表达式之后。

     1 public class Demo4Action extends ActionSupport implements ModelDriven<User>{
     2 
     3     private User user = new User();
     4 
     5     public User getModel() {
     6         return user;
     7     }
     8         
     9     public String demo4(){
    10         System.out.println(user.getName());
    11         System.out.println(user.getAge());
    12         return SUCCESS;
    13     }
    14 }

    原因:是由modelDriven拦截器和params拦截器配合做的。

    十、数据类型的转换(明白原理,实际开发中几乎不用)

    1、开发中的情况:

    实际开发中用户通过浏览器输入的数据都是String或者String[]

    String/String[]————填充模型(set方法)————>POJO(plain old java object)  pojo中有java的数据类型。

    POJO————————获取(get方法)————>页面展示:String

    2、类型转换情况

    写数据:(增,删,改)都是StringString[]数组转换为其他类型。

    读数据:(查)其他类型转换为String

    3Struts2提供的常用类型转换

    a.基本数据类型自动转换。

    b.日期类型:默认按照本地日期格式转换(yyyy-MM-dd)。

    c.字符串数组:默认用逗号+空格,连接成一个字符串。

    4、自定义类型转换器(知道)

    示例:把日期格式按照 MM/dd/yyyy的格式转换

    4.1Struts2中的类型转换器结构:

    4.2、编写类型转换器(编写一个类继承StrutsTypeConverter,实现抽象方法)

     1 public class MyTypeConverter extends StrutsTypeConverter {
     2     
     3     private DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
     4 
     5     public Object convertFromString(Map context, String[] values, Class toClass) {
     6         if(values == null || values.length == 0){
     7             return null;
     8         }
     9         String date = values[0];
    10         if(java.util.Date.class == toClass){
    11             try {
    12                 return format.parse(date);
    13             } catch (ParseException e) {
    14                 e.printStackTrace();
    15             }
    16         }
    17         return null;
    18     }
    19     public String convertToString(Map context, Object o) {
    20         if(o instanceof Date){
    21             Date date = (Date)o;
    22             return format.format(date);
    23         }
    24         return null;
    25     }
    26 }

    4.3、注册类型转换器

    局部类型转换器:只能指定javabean中的属性用

    按照属性来注册。在属性所属的javabean的包下建立一个.properties文件。文件名称:javabean名称-conversion.properties

    全局类型转换器:(推荐)

    按照要转换的数据类型来注册。

    at the top op classpath,建立一个固定名称xwork-conversion.properties的属性文件。

    5、转换失败后的处理(需要掌握)

    当转换失败后,页面提示:

    解决办法:配置回显结果视图

    十一、数据验证

    用户的输入验证,必须做,且工作量巨大。

    1、验证的方式

    客户端验证:javascript

    服务端验证:逻辑验证(我们的代码)

    注意:如果客户端和服务端二选一的话,服务器端的不能省。

    实际开发中:客户端+服务端

    2Struts2的服务端验证

    2.1、编程式验证

    前提:

    动作类必须继承ActionSupport

    在代码中编写验证规则。

    a、针对动作类中的所有动作方法进行验证:

    在动作类中覆盖public void validate()方法。

     1 public class StudentAction extends ActionSupport implements ModelDriven<Student> {
     2 
     3     private Student student = new Student();
     4 
     5     public Student getModel() {
     6         return student;
     7     }
     8     public void validate(){
     9         if(StringUtils.isBlank(student.getUsername())){
    10             addFieldError("username", "用户名不能为空");
    11         }
    12     }
    13     public void validateRegist(){
    14         if(StringUtils.isBlank(student.getUsername())){
    15             addFieldError("username", "用户名不能为空");
    16         }
    17     } 
    18 
    19     public String regist(){
    20         System.out.println("用户名不能为空");
    21         return SUCCESS;
    22     }
    23     
    24     public String update(){
    25         System.out.println("用户名不能为空“);
    26         return SUCCESS;
    27     }
    28 
    29     @SkipValidation
    30     public String findAll(){
    31         return SUCCESS;
    32     }
    33 }

    由此可知,该验证方法会对动作类中的所有动作方法进行验证。

    b、针对动作类中的某个动作方法进行验证

    针对上面的问题,解决办法1:给不需要验证的动作方法添加一个@SkipValidation注解。

    解决办法1和解决办法2的使用时机:需要验证的动作方法少,用解决办法2。需要验证的方法多,用解决方式1。(简单一点:挑少的写)

     所有编程式验证的弊端:硬编码。

    2.2、声明式验证(推荐)

    通过编写验证规则的xml文件。需要验证时,编写xml文件,不要验证,就不写。

    优势:解决了2.1编程式验证的弊端

    a、针对动作类中的所有动作进行验证:在动作类所在的包中,建立一个ActionClassName-validation.xml的文件,内容如下:

    注意:它是针对动作类中的所有动作方法。

    b、针对动作类中的某个动作进行验证:在动作类所在的包中建立一个xml文件,名称为ActionClassName-ActionName-validation.xml。内容如下:

    2.3Struts2内置的常用声明式验证器

    2.3.1位置:

    xwork-core-2.3.15.3.jar\com\opensymphony\xwork2\validator\validator\default.xml

    2.3.2、验证器注入参数

    例如:我们使用requiredstring,默认是去空格,当我们不想去空格时,就可以给验证器注入参数。

    基于字段的:

    基于验证器的:

    3、常用验证器示例

     1 public class Student implements Serializable {
     2 
     3     private String username;
     4     private String password;
     5     private Date birthday;
     6     private String hobby;
     7     private boolean married;
     8     
     9     public String getUsername() {
    10         return username;
    11     }
    12     public void setUsername(String username) {
    13         this.username = username;
    14     }
    15     public String getPassword() {
    16         return password;
    17     }
    18     public void setPassword(String password) {
    19         this.password = password;
    20     }
    21     public Date getBirthday() {
    22         return birthday;
    23     }
    24     public void setBirthday(Date birthday) {
    25         this.birthday = birthday;
    26     }
    27     public String getHobby() {
    28         return hobby;
    29     }
    30     public void setHobby(String hobby) {
    31         this.hobby = hobby;
    32     }
    33     public boolean isMarried() {
    34         return married;
    35     }
    36     public void setMarried(boolean married) {
    37         this.married = married;
    38     }
    39 }
     1 <body>
     2       <s:actionerror/>
     3      <s:form action="saveUser">
     4         <s:textfield name="username" label="用户名"/>
     5         <s:textfield name="age" label="年龄"/>
     6         <s:textfield name="email" label="邮箱"/>
     7         <s:textfield name="password" label="密码" />
     8         <s:textfield name="repassword" label="确认密码"/>
     9         <s:textfield name="score" label="成绩" />
    10         <s:textfield name="url" label="个人主页"/>
    11         <%-- list中的内容:
    12                 相当于创建一个新的List集合
    13         --%>
    14         <s:radio list="{'男','女'}" name="gender" label="性别"/>
    15         <%--
    16             <input type="radio" name="gender" value=""/>17             <input type="radio" name="gender" value=""/>18          --%>
    19         <s:submit value="注册"></s:submit>
    20     </s:form>
    21   </body>
  • 相关阅读:
    易耗品管理 第三四表 查询的存储过程
    [zz]使用vc编译libsvm
    程序调试小bug
    Ubuntu下安装配置OpenNI, OpenCV
    关于Linux下使用OpenCv读取视频打不开的问题
    jQuery实现图片点击放大
    关于 QtDBus 的种种
    javascript计时器的实现
    [QT]没有选择Debug构建方式.为文件的某行设置断点可能会失败
    linux firefox 不显示英文的解决
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5579140.html
Copyright © 2020-2023  润新知