Struts2 在Action中操作数据
servlet存储数据的方式
在servlet中,使用servletcontext对象来存储整个webapp的数据,servletcontext中直接存储整个webapp的公共数据,可使用set|get|removeattribute()来操作数据。
此外servletcontext中还有3类众多的小对象:
- servletconfig 一个servletconfig存储一个servlet的初始化配置参数
- request 一个request存储一个用户的请求参数
- session 一个session存储一个用户的会话信息
这3类对象也用于存储数据,也有对应的set|get|removeattribute()方法。
一共是4类对象,这4类对象均使用map来存储数据,这个map叫做域。
action操作数据的方式
action是用来代替servlet的,servlet用servletcontext来存储数据,action用actioncontext来存储数据。
actioncontext context = actioncontext.getcontext(); //设置、修改、获取参数 context.put("age",18); int age =(int) context.get("age"); //返回值是object,需要强转
actioncontext本身可以存储数据,actioncontext中也有其他的域对象。
actioncontext context = actioncontext.getcontext(); map<string, object> application = context.getapplication(); //获取servletcontext的map对象,即application域 map<string, object> session = context.getsession(); //获取session对象的map对象,即session域 httpparameters parameters = context.getparameters(); //获取所有的请求参数,此对象相当于el内置的param、params对象
map对象、httpparameters对象均有put()、get()、remove()方法,可通过这些方法来操作数据。
获取原生的servlet对象,通过原生的servlet对象来操作数据
struts2提供了三种方式,来获取原生的servlet对象。
1、actioncontext本身可以存储数据,也可以获取servletcontext、request、response三个原生的servlet对象:
actioncontext context = actioncontext.getcontext(); //获取原生的servlet对象。因为get()返回值是object,所以均需强转 servletcontext servletcontext = (servletcontext) context.get("com.opensymphony.xwork2.dispatcher.servletcontext"); httpservletrequest request = (httpservletrequest) context.get("com.opensymphony.xwork2.dispatcher.httpservletrequest"); httpservletresponse response = (httpservletresponse) context.get("com.opensymphony.xwork2.dispatcher.httpservletresponse");
2、key太复杂,记不住,所以struts2提供了工具类servletactioncontext:
//均为servletactioncontext类的静态方法 servletcontext servletcontext = servletactioncontext.getservletcontext(); httpservletrequest request = servletactioncontext.getrequest(); httpservletresponse response = servletactioncontext.getresponse();
3、通过实现接口来获取
public class loginaction extends actionsupport implements servletcontextaware { @override public string execute() throws exception { return super.execute(); } @override public void setservletcontext(servletcontext servletcontext) { } }
实现servletcontextaware接口,只需实现一个方法。tomcat会获取并传入一个servletcontext对象,我们要做的就是写一个servletcontext类型的成员变量,把传入的值赋给它,这样这个action中就可以直接使用servletcontext对象了(成员变量)。
public class loginaction extends actionsupport implements servletcontextaware { private servletcontext servletcontext; @override public string execute() throws exception { return super.execute(); } @override public void setservletcontext(servletcontext servletcontext) { this.servletcontext=servletcontext; } }
要使用servletcontext对象,就实现servletcontextaware接口;
要使用httpservletrequest对象,就实现servletrequestaware接口;
要使用httpservletresponset对象,就实现servletresponseaware接口;
可同时实现这些接口。
其实第2、3种方式底层都是:调用第一种方式获取原生的servlet对象,返回。
actioncontext对象的生命周期
-
servlet是线程不安全的。在webapp运行期间,一个servlet只有一个实例,所有请求(用户)共享这个实例的成员变量,容易引发问题,通常的做法是把可能会被多个用户修改的变量写在方法体中(局部变量)。基于servlet的struts1也是不安全的。
-
struts2是线程安全的。在webapp运行期间,struts2会为每一个请求创建一个新的action实例,处理完这个请求,对应的action实例就销毁。
-
actioncontext对象随action对象的创建而创建,随action对象的销毁而销毁。即actioncontext与servlet中原生的request对象的生命周期一致,所以存储数据可以用actioncontext代替servlet的request。可以用actioncontext来传递数据,但请求参数并不会放在actioncontext的数据区域,不能 actioncontext.getcontext().get("xxx")这样来获取请求参数。
action中获取请求参数的方式
1、获取原生的request对象,通过request对象来获取请求参数
httpservletrequest request = servletactioncontext.getrequest(); string name = request.getparameter("name");
2、通过actioncontext获取httpparameters对象,再通过httpparameters对象来获取请求参数
actioncontext context = actioncontext.getcontext(); httpparameters parameters = context.getparameters(); parameter name = parameters.get("name");
获取的参数是parameter类型。httpparameters相当于一个map。
3、属性驱动
public class loginaction extends actionsupport { private string name; private integer age; //尽管有自动拆箱、装箱,还是尽量用包装类型 public string getname() { return name; } public void setname(string name) { this.name = name; } public integer getage() { return age; } public void setage(integer age) { this.age = age; } @override public string execute() throws exception { return null; } }
将要使用的请求参数写成action的成员变量,并提供setter、getter方法,以及为action提供空参的构造器。
请求参数都是string类型,会先将请求参数转换为对应的成员变量的类型,再调用setter方法赋给对应的成员变量。
只适用于8种基础类型、date类型,date类型对字符串格式有要求,比如2019-09-01。
要求请求参数的name(表单字段的name)与成员变量的变量名相同。
name:<input type="text" name="name"><br /> age:<input type="text" name="age"><br />
属性驱动的缺点:要使用的请求参数很多时,action中会有大量的成员变量、getter、setter方法,很繁杂。
4、对象驱动
将要使用的请求参数封装到一个javabean(实体类)中,作为action的成员变量,action要提供对应的getter、setter方法以及空参构造器:
public class loginaction extends actionsupport { private user user; public user getuser() { return user; } public void setuser(user user) { this.user = user; } @override public string execute() throws exception { system.out.println(user.getname()); return null; } }
需要提供javabean(实体类),这个实体类要具有getter、setter方法、空参构造器:
public class user { private string name; private string age; public string getname() { return name; } public void setname(string name) { this.name = name; } public string getage() { return age; } public void setage(string age) { this.age = age; } }
表单字段的name属性要加上对象名:
name:<input type="text" name="user.name"><br /> age:<input type="text" name="user.age"><br />
name属性的写法与之前不同,可能不习惯。
5、模型驱动
public class loginaction extends actionsupport implements modeldriven<user> { //需要显式创建(new出来),否则为null。 private user user=new user(); @override public user getmodel() { //返回接受请求参数的对象 return user; } @override public string execute() throws exception { return null; } }
需要实现modeldriver<t>接口,只需实现getmodel()方法,返回接受请求参数的对象。
需要显式创建接受请求参数的对象,否则这个对象为null,使用这个对象时会引发空指针异常。但不用给这个对象提供setter、getter方法。
依然需要提供javabean(实体类)。
表单字段的name属性使用原来的写法:
name:<input type="text" name="name"><br /> age:<input type="text" name="age"><br />
模型驱动的缺点:只能有一个model,只能将请求参数封装到一个实体类中。对象驱动则可以有多个对象,可以将参数封装到多个对象中。
6、使用集合封装请求参数
原生的servlet是将请求参数封装到request中,httpparameters是将请求参数封装到httpparameters中,属性驱动是将请求参数封装到action的多个成员变量中,对象驱动、模型驱动都是将请求参数封装到javabean中。
此外还可以使用集合(list或map)来封装请求参数。
-
使用list封装请求参数
public class loginaction extends actionsupport{ private list<string> list; public list<string> getlist() { return list; } public void setlist(list<string> list) { this.list = list; } @override public string execute() throws exception { return null; } }
需要提供getter、setter方法。
表单字段的name属性指定list对象:
name:<input type="text" name="list"><br /> age:<input type="text" name="list"><br />
会把请求字段存储到一个list中,第一个字段存储为list的第一个元素,第二个字段存储为第二个元素......以此类推。
可以指定存储位置:
name:<input type="text" name="list"><br /> age:<input type="text" name="list[3]"><br /> tel:<input type="tel" name="list"><br />
[name字段的值,tel字段的值,null,age字段的值]
指定了下标的,存储在指定的位置上;没有指定下标的,从前往后,存储在闲置的位置(null)上。
-
使用map封装请求参数
public class loginaction extends actionsupport{ private map<string,string> map; public map<string, string> getmap() { return map; } public void setmap(map<string, string> map) { this.map = map; } @override public string execute() throws exception { return null; } }
需要提供getter、setter方法。
表单字段:
name:<input type="text" name="map['name']"><br /> age:<input type="text" name="map['age']"><br />
map是以键值对来存储字段的,所以还需指定key。map对象['key']。
原生的servlet对象是给servlet用的,使用struts2就尽量使用action的方式操作数据。但操作cookie还是原生的servlet对象方便一些。
action中的域(map)与servlet的域对应,在jsp中同样可以使用el表达式取出域中的值。
上一篇: python动态视频下载器
下一篇: C++ const 引用 指针