深入分析JavaWeb Item45 -- Struts2封装请求参数与类型转换_javaweb封装类型转换

  • Action 本身作为model对象,通过成员setter封装

这里写图片描述

  • 创建独立model对象,页面通过ognl表达式封装

这里写图片描述

  • 使用ModelDriven接口,对请求数据进行封装

这里写图片描述

1. 方式一:在动作类中成员变量给予初始值。

在配置文件中struts.xml中

<package name="p1" extends="struts-default">
        <action name="action1" class="com.itheima.actions.PersonAction">
            <result>/result.jsp</result>
        </action>
</package>

编写result.jsp

  <body>
    ${name}
  </body>

编写实现类PersonAction,重写excute()方法

package com.itheima.actions;

import com.opensymphony.xwork2.ActionSupport;

public class PersonAction extends ActionSupport {
    private String name = "刘小晨";
    private String password;
    private int age;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("调用了setName方法");
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String execute() throws Exception {
        System.out.println(name+":"+password+":"+age);
        return super.execute();
    }

}

运行结果为:刘小晨

这种在类的成员变量时,就赋值的方法,亦可以在配置文件中注入动作类的参数值(静态参数设置),Action 本身作为model对象,通过成员setter封装(一个名字为params的拦截器干的)

重新配置struts.xml如下:

  <package name="p1" extends="struts-default">
        <action name="action1" class="com.itheima.actions.PersonAction">
            <!-- 给动作类的实例注入参数值:相当于调用PersonAction.setName("王卫星") -->
            <param name="name">王卫星</param>
            <result>/result.jsp</result>
        </action>
    </package>

运行结果为:王卫星

实际上是由一个叫做staticParams的拦截器做的,可以查看 struts-default.xml配置文件,如果将staticParams这个拦截器删除,则得不到想要的结果

这里写图片描述

此外还有动态参数注入,同样用动作类作为model对象。

编写result.jsp

<body>
    <form action="${pageContext.request.contextPath}/action1" method="post">
        用户名:<input type="text" name="name"/><br/>
        密码:<input type="text" name="password"/><br/>
        年龄:<input type="text" name="age"/><br/>
        <input type="submit" value="保存"/>
    </form>
  </body>

配置文件和动作实现类不变,这里要注意: 表单的字段输入域的name,password, age取值要和动作类的写属性名称一致。

运行结果:表单中name输入的结果。

动态参数的注入也是由一个拦截器来做的:params

2、方式二:动作类和模型分开(我们以表单请求参数为例)

写配置文件struts.xml

<action name="saveStudent" class="com.itheima.actions.StudentAction"></action>

编写动作类StudentAction

package com.itheima.actions;

import com.itheima.domain.Student;
import com.opensymphony.xwork2.ActionSupport;

public class StudentAction extends ActionSupport {
    private Student student = new Student();

    public Student getStudent() {
        System.out.println("调用了getStudent方法");
        return student;
    }

    public void setStudent(Student student) {
        System.out.println("调用了setStudent方法");
        this.student = student;
    }

    public String execute() throws Exception {
        System.out.println(student);
        return NONE;
    }

}

编写模型类Student.java

package com.itheima.domain;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

}

编写访问的页面addStudent.jsp

  <body>
    <form action="${pageContext.request.contextPath}/saveStudent" method="post">
        用户名:<input type="text" name="student.name"/><br/>
        年龄:<input type="text" name="student.age"/><br/>
        <input type="submit" value="保存"/>
    </form>
  </body>

这样上述就将模型(Student)和动作类(StudentAction)分开了,在页面中,我们可以用student.name和student.age来封装请求参数了。

主要原理如下:

  1. 框架创建了一个Student的实例,通过调用setStudent(Student s),传递对象
  2. 框架再调用StudentAction的getStudent(),方法,得到刚刚创建的对象
  3. 紧接着,调用student实例的setName和setAge方法,设置值。

3. 方式三:模型驱动(面试)(与后面ValueStack值栈有关)

编写struts.xml配置文件

<action name="saveCustomer" class="com.itheima.actions.CustomerAction"/>

编写CustomerAction的动作类

package com.itheima.actions;

import com.itheima.domain.Customer;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
//使用模型驱动:
public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{
    private Customer customer = new Customer();//这里一定要new()出一个实体类。

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(customer);
        return NONE;
    }

    public Customer getModel() {
        return customer;
    }

}

编写实体类Customer.java

package com.itheima.domain;

import java.io.Serializable;

public class Customer implements Serializable {
    private String name;
    private String city;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    @Override
    public String toString() {
        return "Customer [name=" + name + ", city=" + city + "]";
    }

}

编写addCustomer.jsp页面

  <body>
    <form action="${pageContext.request.contextPath}/saveCustomer.action" method="post">
        用户名:<input type="text" name="name"/><br/>
        城市:<input type="text" name="city"/><br/>
        <input type="submit" value="保存"/>
    </form>
  </body>

这里可以直接写name和city来封装请求参数,而不需要些customer.name和customer.city。

注:模型驱动实际上是由一个拦截器来做的。modelDriven拦截器来做。把getModel方法返回的对象,压入一个叫做ValueStack的栈顶。struts框架就会根据表单的name属性,调用对应栈顶对象的setter方法,从而把请求参数封装进来。可以看源码:
注意这一定要new出来! 否则框架调用CustomerAction的getCustomer()方法,得到返回值为null。

2、 封装数据到集合类型中

Struts2 还允许填充 Collection 里的对象, 这常见于需要快速录入批量数据的场合

  • 类型转换与Collection配合使用

这里写图片描述

  • 类型转换与Map配合使用

这里写图片描述

实例:

编写配置struts.xml

<action name="collectionAction1" class="com.itheima.actions.CollectionAction"/>
<action name="collectionAction2" class="com.itheima.actions.CollectionAction"/>
<action name="collectionAction3" class="com.itheima.actions.CollectionAction"/>

编写动作类CollectionAction

package com.itheima.actions;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import com.itheima.domain.Employee;
import com.opensymphony.xwork2.ActionSupport;

public class CollectionAction extends ActionSupport {
    private String[] hobby;//数组
    private Collection<Employee> employees;//集合

    private Map<String, Employee> emps;//map

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    public Collection<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(Collection<Employee> employees) {
        this.employees = employees;
    }

    public Map<String, Employee> getEmps() {
        return emps;
    }

#### 结束  

一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

![](https://img-blog.csdnimg.cn/img_convert/45f2869b91b538dd3bb3290ba13bc806.png)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值