Struts2 (下)
接收参数
当发送一个请求时,除了使用RequestApi来接收参数之外,Struts2内部提供了3种接收参数的方式
接收参数的方式
1. 提供属性set方法的方式
在Action当中提供对应属性的set方法,会自动接收参数,并且会自动做类型转换
使用方式
index.jsp
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	用户名:<input type="text" placeholder="请输入用户名..." name="username"><br />
	年龄:<input type="text" placeholder="请输入年龄..." name="age"><br />
	爱 好:
	<input type="checkbox" value="足球" name="hobby">足球
	<input type="checkbox" value="篮球" name="hobby">篮球
	<input type="checkbox" value="乒乓球" name="hobby">乒乓球<br />
	<input type="submit" value="提交">
</form>
struts.xml
<struts>
    <package name="struts" extends="struts-default" namespace="/">
		<action name="myform" class="com.xzh.struts2.MyFormAction">
			<!-- 结果页 -->
			<result name="success">/myxq.jsp</result>
		</action>
    </package>
</struts>
MyFormAction.java
public class MyFormAction extends ActionSupport {
	private String username;
	private int age;
	private List hobby;
	public void setUsername(String username) {
		this.username = username;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void setHobby(List hobby) {
		this.hobby = hobby;
	}
	public String execute() {
		System.out.println(username);
		System.out.println(age);
		System.out.println(hobby);
		return null;
	}
}
缺点:接收少量数据可以,如果大量数据,还得要自己手动封装成对象
2. 页面中提供表达式方式
- 创建一个接收参数的domain模型
- 在Action当中提供一个对象属性,并要提供该对象属性的get/set方法
- 在jsp页面当中发送参数时要带上Action当中的对象属性名称
使用方式
User.java
public class User {
	private String username;
	private Integer age;
	private List hobby;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public List getHobby() {
		return hobby;
	}
	public void setHobby(List hobby) {
		this.hobby = hobby;
	}
	@Override
	public String toString() {
		return "User{" + "username='" + username + '\'' + ", age=" + age + ", hobby=" + hobby + '}';
	}
}
index.jsp
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	用户名:<input type="text" placeholder="请输入用户名..." name="user.username"><br />
	年龄:<input type="text" placeholder="请输入年龄..." name="user.age"><br />
	爱 好:
	<input type="checkbox" value="足球" name="user.hobby">足球
	<input type="checkbox" value="篮球" name="user.hobby">篮球
	<input type="checkbox" value="乒乓球" name="user.hobby">乒乓球<br />
	<input type="submit" value="提交">
</form>
struts.xml
<struts>
    <package name="struts" extends="struts-default" namespace="/">
		<action name="myform" class="com.xzh.struts2.myform.MyFormAction">
			<!-- 结果页 -->
			<result name="success">/myxq.jsp</result>
		</action>
    </package>
</struts>
MyFormAction.java
public class MyFormAction extends ActionSupport {
	private User user;
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public String execute() {
		System.out.println(user);
		return null;
	}
}
3. 采用模型驱动方式
- 创建一个接收参数的domain模型
- 在Action当中实现ModelDriven接口
- 实现接口方法getModel()
- 创建一个模型对象,在接口方法中返回
使用方式
User.java
public class User {
	private String username;
	private Integer age;
	private List hobby;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public List getHobby() {
		return hobby;
	}
	public void setHobby(List hobby) {
		this.hobby = hobby;
	}
	@Override
	public String toString() {
		return "User{" + "username='" + username + '\'' + ", age=" + age + ", hobby=" + hobby + '}';
	}
}
index.jsp
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	用户名:<input type="text" placeholder="请输入用户名..." name="username"><br />
	年龄:<input type="text" placeholder="请输入年龄..." name="age"><br />
	爱 好:
	<input type="checkbox" value="足球" name="hobby">足球
	<input type="checkbox" value="篮球" name="hobby">篮球
	<input type="checkbox" value="乒乓球" name="hobby">乒乓球<br />
	<input type="submit" value="提交">
</form>
struts.xml
<struts>
    <package name="struts" extends="struts-default" namespace="/">
		<action name="myform" class="com.xzh.struts2.myform.MyFormAction">
			<!-- 结果页 -->
			<result name="success">/myxq.jsp</result>
		</action>
    </package>
</struts>
MyFormAction.java
public class MyFormAction extends ActionSupport implements ModelDriven<User>{
	private User user = new User();
	@Override
	public User getModel() {
		return user;
	}
	public String execute() {
		System.out.println(user);
		return null;
	}
}
接收参数错误
- 只要任何一个拦截器在执行的过程当中,都会向错误信息中去添加错误消息。
- 最后workflow会检查错误信息当中是否有错误的消息
- 如果没有,就直接到目标action
- 如果有,就会跳转到input逻辑视图

在开发时,可以配置一个input逻辑视图,错误时,可以在跳转到自己指定的页面, 在页面中可以显示错误信息


接收复杂类型封装到List集合
创建jsp页面
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	商品名称:<input type="text" placeholder="请输入商品名称..." name="name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="price"><br />
	<hr>
	商品名称:<input type="text" placeholder="请输入商品名称..." name="name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="price"><br />
	<hr>
	商品名称:<input type="text" placeholder="请输入商品名称..." name="name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="price"><br />
	<input type="submit" value="提交">
</form>
创建页面对象模型
public class Goods {
	private String name;
	private Double price;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}';
	}
}
编写struts.xml
<struts>
    <package name="struts" extends="struts-default" namespace="/">
		<action name="myform" class="com.xzh.struts2.myform.MyFormAction">
			<!-- 结果页 -->
			<result name="success">/myxq.jsp</result>
		</action>
    </package>
</struts>
创建对应Action
public class MyFormAction extends ActionSupport {
	private List<Goods> goodsList;
	public List<Goods> getGoodsList() {
		return goodsList;
	}
	public void setGoodsList(List<Goods> goodsList) {
		this.goodsList = goodsList;
	}
	public String execute() {
		System.out.println(goodsList);
		return null;
	}
}
在jsp当中添加表达式
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	商品名称:<input type="text" placeholder="请输入商品名称..." name="goodsList[0].name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="goodsList[0].price"><br />
	<hr>
	商品名称:<input type="text" placeholder="请输入商品名称..." name="goodsList[1].name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="goodsList[1].price"><br />
	<hr>
	商品名称:<input type="text" placeholder="请输入商品名称..." name="goodsList[2].name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="goodsList[2].price"><br />
	<input type="submit" value="提交">
</form>
接收复杂类型封装到Map集合
基本上与List相同。
创建对应Action
public class MyFormAction extends ActionSupport {
	private Map<String,Goods> goodsMap;
    public Map<String, Goods> getGoodsMap() {
        return goodsMap;
    }
    public void setGoodsMap(Map<String, Goods> goodsMap) {
        this.goodsMap = goodsMap;
    }
	public String execute() {
		System.out.println(goodsMap);
		return null;
	}
}
jsp
<form action="${pageContext.request.contextPath }/myform.action"
	method="get">
	商品名称:<input type="text" placeholder="请输入商品名称..." name="goodsMap['one'].name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="goodsMap['one'].price"><br />
	<hr>
	商品名称:<input type="text" placeholder="请输入商品名称..." name="goodsMap['two'].name"><br />
	商品价格:<input type="text" placeholder="请输入商品价格..." name="goodsMap['two'].price"><br />
	<input type="submit" value="提交">
</form>
key值为自己取的一个值
OGNL
什么是OGNL
- OGNL是Object-Graph Navigation Language的缩写,
- 它是一种功能强大的表达式语言,通过它简单一致的表达式语法,
- 可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
OGNL与EL表达式对比
- OGNL对象图导航语言,比EL表达式强大很多倍的语言
- EL表达式只能从域中获取数据
- OGNL可以调用对象的方法,获取struts的值栈的数据。
- OGNL是第三方的表达式语言,用它来获取struts中值栈的数据
OGNL功能
- 支持运算符(如+-*/)
- 支持对象方法调用,如xxx.doSomeSpecial();
- 支持类静态的方法调用和值访问
- 支持赋值操作和表达式串联
- 访问OGNL上下文
- 操作集合对象
- 可以直接new一个对象
OGNL使用要素
- 表达式
- 根对象
- Context对象(非根对象)
OGNL入门
- OGNL核心OgnlContext,本质就是一个map
java程序使用ognl
1. 获取root中的数据
可以向root当中存放Java对象
不需要加#号

2. 获取context中的数据
取数据时需要加#

3. 获取对象方法

4. 获取对象静态方法

struts2中使用ONGL
在jsp当中引入struts的标签库
直接在jsp当中使用OGNL

访问静态方法
- 默认是不让访问静态成员
- 需要开启一个常量 struts.ognl.allowStaticEmthodAccess


值栈
什么是值栈
ValueStack实际上就是一个容器。是一个接口,实现类为OgnlValueStack
当用户每次访问action对象的业务方法时, 会先创建ActionContext对象,OgnlValueStack对象,Action对象
它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。
Struts框架中的数据就都保存到了ValueStack中,不存到域当中了,存到域当中只能在页面中把它取出来,存到值栈当中可以在任何地方取出数据(页面中取出、action中取出、在配置文件当中取出)
ValueStack贯穿整个action的生命周期
action一旦创建,就会创建一个valuestack对象
值栈的内部结构




值栈与ActionContext的关系
可以通过ActionContext获得到值栈
ActionContext上下文对象
- 当请求过来的时候,执行StrutsPrepareAndExecuteFilter过滤器当中的doFilter方法
- 在这个方法当中创建ActionContext
- 在创建ActionContext过程中,创建ValueStack对象
- 将valueStack对象传递给ActionContext对象。通过ActionContext获取值栈对象
- ActionContext对象之所以以够访问servlet的API(域对象的数据)
- 就是因为内部有值栈的引用
Struts2 (下)的更多相关文章
- struts2下velocity做视图如何访问request,session等内置对象,如:原来webwork的$req
		struts2下velocity做视图如何访问request,session等内置对象(转) velocity 内置对象 struts2 requestStruts2环境下用velocity做视图时访 ... 
- uploadify在struts2下的使用
		1.首先准备uploadify上传插件包,拷贝到项目目录下 2.注意其中的特殊文件:uploadify-init.js文件,是包含了封装后的特殊函数: /** * uploadify上传插件相关JS ... 
- Struts2框架学习第二章——Struts2下的HelloWorld
		本章要点 — Struts 2的下载和安装 — 纯手工创建一个Web应用 — 纯手工创建一个Struts 2应用 — 实现Struts 2的Action — 配置Struts 2的Action — ... 
- Java进阶知识02 Struts2下的拦截器(interceptor)和 过滤器(Filter)
		一.拦截器 1.1.首先创建一个拦截器类 package com.bw.bms.interceptor; import com.opensymphony.xwork2.ActionContext; i ... 
- Java进阶知识01 Struts2下的 jquery+ajax+struts 技术实现异步刷新功能
		1.效果图示 横线上方的部分不动(没有刷新),下方实现刷新(异步刷新) 2.实现步骤 jquery+ajax+struts技术实现异步刷新功能的步骤: 1.需要用到 jquery+ajax+st ... 
- 未解决:为什么在struts2下新建ognl的包,会出错?
		首先开始在src下新建了一个名叫ognl的包: 发现在其中放置了一个loginAction,即使是最简单的跳转都不能实现: 直接抛出了java.lang.Exception; 传递参数更出现了异常: ... 
- Struts2下的<result>中的type整理
		1.<result name="处理结果名" type="相应结果类型">“响应内容”</result> 解释:name的值shift指 ... 
- struts2下s:iterator取不出值
		1:问题起因:通过action方法连接数据库取出Arraylist集合,在前台页面遍历显示无数据,用s:debug查看 stack里有值,用了各种方法,包括session传值,但是仍然取不出来. 2: ... 
- struts2下实现的json传递list,object。
		必须的jar: java bean: package upload.progress.action; public class music { private String name; private ... 
- 11、Struts2 的文件上传和下载
		文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ... 
随机推荐
- git 放弃本地修改操作
			如果在修改时发现修改错误,而要放弃本地修改时, 一, 未使用 git add 缓存代码时. 可以使用 git checkout -- filepathname (比如: git checkout ... 
- [Openwrt扩展中篇]添加Aria2和webui
			上一篇说了我构建了简单的网络硬盘,这一篇说的是我构造的aria2和webui,大概是这样我觉得有了网络硬盘,那么我是不是可以远程下载呢,翻阅了网上资料发现迅雷的Xware貌似不更新了,然后我发现了ar ... 
- 文件读取 FILE
			需要了解的概念 [数据流][缓冲区(Buffer)][文件类型][文件存取方式][借助文件指针读写文件] 需要理解的知识点包括:数据流.缓冲区.文件类型.文件存取方式 1.1 数据流: 指程序与数据的 ... 
- Go语言的接口interface、struct和组合、继承
			Go语言的interface概念相对于C++中的基类,通过interface来实现多态功能. 在C++中,当需要实现多态功能时,步骤是首先定义一个基类,该基类使用虚函数或者纯虚函数抽象了所有子类会用到 ... 
- 20155303 2016-2017-2 《Java程序设计》第十周学习总结
			20155303 2016-2017-2 <Java程序设计>第十周学习总结 目录 学习内容总结 网络编程 数据库 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ... 
- 配置replica set的常见问题
			总有人问起配置ReplicaSet不成功,总结了一下基本上的可能性就几种,检查步骤如下: 假设三台机器的IP分别是 A: 192.168.1.2 a.test.com B:192.168.1.3 b. ... 
- Linux configure关于交叉编译的参数设置【转】
			转自:http://blog.csdn.net/darennet/article/details/9003005 configure的参数众多,一般包括如下 --srcdir=DIR 这个选项对安装没 ... 
- mysql测试工具 -> mysqlslap
			一.简介 mysqlslap是mysql自带的基准测试工具 优点:查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新,给出了性能测试数据而且提供了多种引擎的性能比 ... 
- 排序算法——Shell排序
			二.Shell排序 Shell排序也叫“缩减增量排序”(disminishing increment sort),基于插入排序进行. Shell建议的序列是一种常用但不理想的增量序列:1,...,N/ ... 
- MongoDB(3.6.3)的用户认证初识
			Windows 10家庭中文版,MongoDB 3.6.3, 前言 刚刚安装好了MongoDB,启动了服务器-mongod命令,启动了MongoDB shell-mongo命令,不过,全程都没有使用u ... 
