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、paramValues对象
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(); HttpSession session = ServletActionContext.getRequest().getSession();
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");
请求参数封装在request对象的parameters对象中,不是直接封装在request对象中,request中直接封装的是setAttribute()的数据。
把request作为一个大Map,里面还有一个小Map,小Map用于封装请求参数。 Map<String, String[]> parameterMap = request.getParameterMap(); 。
Object obj=request对象.getAttribute("user"); 获取的是setAttribute()存入的数据。
String user = request对象.getParameter("user"); 获取的才是请求参数(从小Map中查找数据)。
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方法,很繁杂。
静态参数注入:
<action name="LoginAction" class="action.LoginAction">
<param name="user">张三</param>
<param name="age">18</param> <result name="success">index.jsp</result>
<result name="fail>login.jsp</result>
</action>
在<param>中指定Action成员变量的值,不常用。
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用的,在Action中使用原生的Servlet对象,会使Action耦合Serlvet。
使用Struts2就尽量使用Action的方式操作数据,除非使用原生的Servlet对象会更加方便,比如操作Cookie。
Action中的域(Map)与Servlet的域对应,在JSP中同样可以使用EL表达式取出域中的值。
Struts2 在Action中操作数据的更多相关文章
- 在struts2的action中操作域对象(request、session)
在struts2的Action中,操作域对象一共有三种方式: 1.ActionContext(与servelt API无关联): //相当于request ActionContext.getConte ...
- JavaWeb_(Struts2框架)Action中struts-default下result的各种转发类型
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- 9.Struts2在Action中获取request-session-application对象
为避免与Servlet API耦合在一起,方便Action类做单元测试. Struts2对HttpServletRequest.HttpSession.ServletContext进行了封装,构造了三 ...
- struts2的action中获得request response session 对象
在struts2中有两种方式可以得到这些对象 1.非IoC方式 要获得上述对象,关键Struts 2中com.opensymphony.xwork2.ActionContext类.我们可以通过它的静态 ...
- struts2对action中的方法进行输入校验---xml配置方式(3)
上面两篇文章已经介绍了通过编码java代码的方式实现action方法校验,这里我们介绍第二种方式:xml配置文件 首先我们来看一个样例: ValidateAction.java: package co ...
- struts2对action中的方法进行输入校验(2)
struts2输入校验流程: 1.类型转换器对请求參数运行类型转换,并把转换后的值赋给aciton中的属性 2.假设在运行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext, ...
- 关于在Struts2的Action中使用domain模型接收参数的问题
最近在搭建一个最新的ssh2框架,今天在调试的时候,发现了一个以前一直没有注意过的问题,我在Action中使用域模型的方式去接收jsp画面中的参数的时候,发现参数总是接收不完,头一次遇到这种问题,现在 ...
- 理解Struts2的Action中的setter方法是怎么工作的
接触过webwork和Struts2的同行都应该知道, 提交表单的时候,只要Action中的属性有setter 方法,这些表单数据就可以正确赋值到Action中属性里:另外对于Spring配置文件中声 ...
- 在Struts2的Action中获得request response session几种方法
转载自~ 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action中取得这些对象呢?Struts2为我们提供了四种方式.分别为se ...
随机推荐
- RdKafka文档翻译
函数string rd_kafka_err2str ( integer $err ) 将rdkafka错误代码转换为字符串 integer rd_kafka_errno2err ( integer $ ...
- TCP协议如何保证可靠传输
TCP协议如何保证可靠传输 概述: TCP协议保证数据传输可靠性的方式主要有: (校 序 重 流 拥) 校验和: 发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化.如果收到段的检 ...
- 6.1 Spark SQL
一.从shark到Spark SQL Hive能够把SQL程序转换成map-reduce程序 可以把Hadoop中的Hive看作是一个接口,主要起到了转换的功能,并没有实际存储数据. Shark即 ...
- Linux通过端口号查看使用进程-结束进程
1. 查看进程(参数带 - 与不带有区别): command [options] 例:ps -a(配合其他options参数以展示进程更多参数) ps -ef | grep 进程名(返回值是该进程的 ...
- 对CNN 的理解
CNN 的强大之处在于它的多层结构能自动学习特征,并且可以学习到多个层次的特征:较浅的卷积层感知域较小,学习到一些局部区域的特征. 较深的卷积层具有较大的感知域,能够学习到更加抽象一些的特征.这些抽象 ...
- Python 链表(linked list)
链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 链表由一系列结点组成,结点可以在运行时动态生成 优点 由于不必须按顺序存储,链表在插入.删除的时候 ...
- mq代替db
系统有个很严重的性能问题,法国人浪费了半年多都没有解决,他们试图从sql的角度分析哪里能有改善,大方向错了,再努力也没用. 我接手以后,也走了点弯路,一上手觉得肯定能用cache解决问题,结果cach ...
- (二十四)golang--错误处理
在默认情况下,遇到错误时,程序会崩溃: 在发生错误时,我们可以捕获错误,使程序可以继续运行,并抛出错误提示: 错误处理: (1)Go语言追求简洁优雅,所以不支持传统的try catch finally ...
- Python连载19-装饰器
一.检视一个函数相同的另一种方法 利用属性:函数._name def hello(): print("我是一个测试程序") f = hello print(f.__name__) ...
- CDN的智能调度,链路优化的详细解答
您的用户在请求资源的过程中,可能受到网络.地域.带宽等影响,无法保证请求一定是按照最优访问路径进行传递,猫云 CDN 通过对全网链路进行实时监控,结合自研的 GSLB 调度体系和智能路由技术,从以下几 ...