欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Struts2的API&数据封装(二)

程序员文章站 2022-05-19 14:21:30
一 Servlet的API的访问 1 完全解耦和的方式 完全看不到request、response、session。 (1)创建jsp界面 (2)编写action (3)struts_xml 运行效果图 调用put方法相当于往request域中存数据注意:这种方式只能获得像 request sess ......

一 servlet的api的访问

1 完全解耦和的方式

 完全看不到request、response、session。

 (1)创建jsp界面

<h1>struts2的servlet的api的访问</h1>
<h3>完全解耦和的方式,方式一</h3>
<form method="post" action="${pagecontext.request.contextpath}/requestaction.action" >
    姓名:<input type="text" name="name">
    密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>

(2)编写action

/**
 * 访问servlet api的完全解耦和的方式一
 */
public class requestaction extends actionsupport {
    public requestaction() {
        system.out.println("action对象被创建了");
    }

    @override
    public string execute() throws exception {
        actioncontext actioncontext=actioncontext.getcontext();
        map<string, object> map = actioncontext.getparameters();
        for (string key:map.keyset()
             ) {
           string[] values  = (string[]) map.get(key);
            system.out.println(key +"   "+arrays.tostring(values));
        }
        //存值
        actioncontext.put("attname","attvalue");
        actioncontext.getsession().put("sessname","sessvalue");
        actioncontext.getapplication().put("appname","appvalue");
        return success;
    }
}

(3)struts_xml

 <action name="requestaction" class="com.itheima.demo1.requestaction">
            <result name="success" type="redirect">/demo1/demo2.jsp</result>
        </action>

运行效果图

Struts2的API&数据封装(二)

调用put方法相当于往request域中存数据
注意:这种方式只能获得像 request session application集合中的值,不能操作对象的本身的方法

 


 

2 使用servlet的api的原生方式(这种必须要会)

编写jsp

 

<h3>使用原生的方式,方式二</h3>
<form method="post" action="${pagecontext.request.contextpath}/requestaction2.action" >
    姓名:<input type="text" name="name">
    密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>

 

编写action

public class requestaction2 extends actionsupport {
    @override
    public string execute() throws exception {
        httpservletrequest request = servletactioncontext.getrequest();

        map<string, string[]> map = request.getparametermap();
        for (string key:map.keyset()
             ) {
            string[] values = map.get(key);
            system.out.println(key+"   "+arrays.tostring(values));
        }
        request.setattribute("attname","attvalue");
        request.getsession().setattribute("sessname","sessvalue11");
        servletactioncontext.getservletcontext().setattribute("appname","appvalue11");
        return success;
    }
}

运行效果图

Struts2的API&数据封装(二)

 

 这种方式既可以操作域中的数据,也可以操作对象的方法


 

3 接口注入的方式(这种方式很少用,了解)

action类

 

public class requestaction3 extends actionsupport implements servletrequestaware,servletcontextaware {

    private httpservletrequest request;
    private servletcontext context;//可以通过快捷键来生成

    public requestaction3() {
        system.out.println("action被创建了");
    }

    @override
    public string execute() throws exception {
        map<string, string[]> map = request.getparametermap();
        for (string key:map.keyset()
             ) {
            string[] values = map.get(key);
            system.out.println(key+""+arrays.tostring(values));
        }
        request.setattribute("attname","attvalues111");
        request.getsession().setattribute("sessname","sessvalues2");
        context.setattribute("appname","appvalues3");//存到application中
        return super.execute() ;//这里是返回sucess,可以查看源代码
    }

    @override
    public void setservletrequest(httpservletrequest request) {
        this.request=request;
    }

    @override
    public void setservletcontext(servletcontext servletcontext) {
        this.context=servletcontext;
    }
}

 


servlet是单例的,只会创建一个对象。而action是多例的,每一次请求都会创建一个对象
action是线程安全的,action是多例的,在类中定义成员变量不会有线程安全的问题

 

二 配置结果页面

1 全局结果页面

全局结果页面,指的是这个包底下的都有效

<global-results>
            <result name="success">/demo1/demo2.jsp</result>
</global-results>

 

2 局部结果页面

局部结果页面,针对当前的action有效

<action name="requestaction" class="com.itheima.demo1.requestaction">
            <result name="success" type="redirect">/demo1/demo2.jsp</result>
        </action>

 


result就是用于配置页面的跳转的,里面有两个属性 name type

name的默认值是success,假如返回值是success就不需要写了
type属性:页面跳转的类型,前两种类型经常用,记住
  dispacher 默认值,请求转发,action转发jsp
  redirect 重定向 action重定向jsp
  chain 转发 ,action转发到action
  redirctaction 重定向,action重定向action (这个案例中就用到了这个)
  stream struts2中提供文件下载的功能(了解)


 

 

三 数据封装

1 方式一属性驱动:提供set方法
 提供属性set方法的方式 (这种方式很少用,比如文件下载,传过来个文件名)
jsp页面
<h1>struts2的数据封装</h1>
<h3>方式一属性驱动:提供set方法</h3>
<form action="${pagecontext.request.contextpath}/action1" method="post">
<s:fielderror/>
    用户名:<input type="text" name="name"/><br>
    密码:<input type="text" name="password" /><br>
    年龄:<input type="text" name="age"/><br>
    生日:<input type="text" name="birthday"/><br>
    工资:<input type="text" name="salary"/><br>
    <input type="submit" value="提交">
</form>
action类
/**
 * 方式一属性驱动:提供set方法
 */
public class action1 extends actionsupport {
    private string name;
    private  string password;
    private integer age;
    private date birthday;
    private double salary;//工资
    //需要提供set方法


    public void setname(string name) {
        this.name = name;
    }

    public void setpassword(string password) {
        this.password = password;
    }

    public void setage(integer age) {
        this.age = age;
    }

    public void setbirthday(date birthday) {
        this.birthday = birthday;
    }

    public void setsalary(double salary) {
        this.salary = salary;
    }

    @override
    public string execute() throws exception {
        system.out.println(name);
        system.out.println(password);
        system.out.println(age);
        system.out.println(birthday);
        system.out.println(salary);
        return none;
    }
}



方式二属性驱动:页面中提供表达式(可以同时向多个对象中同时封装数据)

  在action中创建一个私有对象,提供get和set方法,一定要提供get方法
  在页面中用user.的方式

jsp界面
<h3>方式二:属性驱动,提供页面表达式</h3>
<form action="${pagecontext.request.contextpath}/action2" method="post">
    用户名:<input type="text" name="user.name"/><br>
    密码:<input type="text" name="user.password" /><br>
    年龄:<input type="text" name="user.age"/><br>
    生日:<input type="text" name="user.birthday"/><br>
    工资:<input type="text" name="user.salary"/><br>
    <input type="submit" value="提交">
</form>

编写action

/**
 * 二 属性驱动:页面中提供表达式
 */
public class action2 extends actionsupport {
    //创建一个私有对象,提供get和set方法,一定要提供get方法
    private user user;

    public user getuser() {        //在拦截器中获取到user对象
        return user;
    }

    public void setuser(user user) {
        this.user = user;
    }

    @override
    public string execute() throws exception {
        system.out.println(user);
        return none;
    }
}

 

方式三:采用模型驱动的方式(开发中最常用的方式)

模型驱动:只须实现一个接口,提供一个对象,页面不用改
在action中实现模型驱动的接口(modeldriven),后面跟上对象的泛型
使用的对象,必须手动提供对象的实例(new这个对象)
缺点:只能同时向一个对象中封装数据(一般开发中都是同时向一个对象中封装数据)

jsp界面

<h3>方式一:提供set方法</h3>
<form action="${pagecontext.request.contextpath}/action3" method="post">
    用户名:<input type="text" name="name"/><br>
    密码:<input type="text" name="password" /><br>
    年龄:<input type="text" name="age"/><br>
    生日:<input type="text" name="birthday"/><br>
    工资:<input type="text" name="salary"/><br>
    <input type="submit" value="提交">
</form>

编写action类

**
 * 方式三:采用模型驱动的方式
 */
public class action3 extends actionsupport implements modeldriven<user> {
    private user user=new user();//创建实例
    @override
    public user getmodel() {
        //实例化对象

        return user;
    }

    @override
    public string execute() throws exception {
        system.out.println(user);
        return none;
    }
}

2 封装复杂数据到list集合中

jsp界面

<h1>struts2封装复杂数据</h1>
<h3>封装数据到list集合中</h3>
<form action="${pagecontext.request.contextpath}/productaction1.action" method="post">
    商品名称:<input type="text" name="products[0].name"><br>
    商品价格:<input type="text" name="products[0].price"><br>
    商品名称: <input type="text" name="products[1].name"><br>
    商品价格: <input type="text" name="products[1].price"><br>
    商品名称: <input type="text" name="products[2].name"><br>
    商品价格: <input type="text" name="products[2].price"><br>
    <input type="submit" value="提交数据">

</form>

编写action

/**
 * 封装数据到list集合中
 */
public class productaction1 extends actionsupport {
        private list<product> products;

    public list<product> getproducts() {
        return products;
    }

    public void setproducts(list<product> products) {
        this.products = products;
    }

    @override
    public string execute() throws exception {
        system.out.println(products);
        return none;
    }
}

 

3封装复杂数据到map集合中

jsp界面

<h3>封装数据到map集合中</h3>
<form action="${pagecontext.request.contextpath}/productaction2.action" method="post">
    商品名称:<input type="text" name="map['one'].name"><br>
    商品价格:<input type="text" name="map['one'].price"><br>
    商品名称: <input type="text" name="map['two'].name"><br>
    商品价格: <input type="text" name="map['two'].price"><br>
    商品名称: <input type="text" name="map['three'].name"><br>
    商品价格: <input type="text" name="map['three'].price"><br>
    <input type="submit" value="提交数据">
</form>

编写action类

**
 * 封装数据到map集合中
 */
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;
    }

    @override
    public string execute() throws exception {
        //遍历map集合
        for (string key :map.keyset()
                ) {
            product product = map.get(key);
            system.out.println(key+"  "+product);
        }
        return none;
    }
}

4 写程序时遇到的错误

(1)input视图(报了input的异常,可以配一个input)
  引入一个struts2的标签库
  invalid field value for field "age".
(2)jsp页面中报element is not closed

  两个form表单写到了一个表单中