Struts2 进阶
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2 进阶相关的知识,希望对你有一定的参考价值。
1. OGNL概述
× Web阶段,EL表达式是在jsp中获取域对象里面的值
× Struts阶段,OGNL一个独立项目,并非Struts2的组件,只是经常与struts2一起使用
- OGNL在Strust中主要用于操作值栈数据,一般与struts标签一起使用操作值栈
- 操作OGNL
· 导如Jar包并在页面中引入标签库 <%@ taglib uri = "/struts-tags" prefix="s"%>
· 使用ognl,value属性值:ognl表达式
eg : 计算str的长度 <s:property value=" ‘Text‘.length() "/>
- OGNL表达式 # 使用:使用#获取ValueStack中的Context数据
<s:property value="#域对象的Key.属性名">
<s:property value="#request.req">
- OGNL表达式 % 使用: struts2标签中的表单标签,不能识别OGNL表达式,必须使用%来声明
· <s:textfield />等同于<input type="text">
· <s:textfield name = "文本框名" value="%{OGNL表达式}"> </s:textfield>
· 例如:<s:textfield name = "username" value="%{request.req}"> </s:textfield>
2. 值栈
Web阶段 |
Struts阶段 |
- 域对象为Web的存储机制(存值/取值) - 在Servlet内将数据保存在域对象中 - 在页面使用EL表达式获取数据 |
- 值栈为Struts2的存储机制((存值/取值)) - 在Action类内将数据保存到值栈中 - 在页面使用OGNL表达式获取 |
1) Servlet与Action的区别
- Servlet:默认在第一次访问时候创建,且创建一次,单实例。
- Action:每次访问Action便会创建一个action对象,多实例。
2) 值栈存储位置:值栈存在于action实例对象中,且实例对象中只有一个值栈。 (值栈对象内有Action的引用)
3) 获取值栈对象:
- 使用ActionContext.getContext()获取context对象
- 调用context.getValueStack()获取值栈对象
3. 内部结构
root:(List),一般操作root内的数据
context:(Map):存放对象引用
key | request | session | application | parameters | attr |
value | request对象引用 | session对象引用 | ServletContext对象引用 | 传递相关参数 | 相同属性名(name),名称获取域范围最小的值(value) |
× <s:debug>调试标签,在页面中引用向页面输出stack的结构
4. 存储数据
配置文件与页面
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="demo1" extends="struts-default" namespace="/"> <action name="stack_*" class="code.actionStack.ValueStack{1}"> <result name="stack_1">/ValueStack.jsp</result> ..... </action> </package> </struts>
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <body> <s:debug/> </body> </html>
方式一:在action中定义变量,生成变量的get方法( 主要使用 ),数据保留在action类中,减少资源占用。
× getXxx中的Xxx,会在值栈中将对象的Property Name命名为xxx
import com.opensymphony.xwork2.ActionSupport; @SuppressWarnings("serial") public class ValueStack1 extends ActionSupport { // 1.设置变量 private String text; // 2.生成get方法 public String getText() { return text; } @Override public String execute() throws Exception { // 3.在执行方法内向变量设置 text = "测试文本"; return "sccuess"; } }
方式一执行结果:该数据将被存储在Action类中,且能减少空间占用
方式二:获取值栈对象,调用值栈对象内的set方法 (将以Map形式存储到值栈中)
import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; @SuppressWarnings("serial") public class ValueStack1 extends ActionSupport { @Override public String execute() throws Exception { // 方式二:使用set方法 // 1.获取上下文 ActionContext ac = ActionContext.getContext(); // 2.获取值栈对象 ValueStack vs = ac.getValueStack(); // 3.使用set方法 vs.set("text", "测试文本"); return SUCCESS; } }
方式二执行结果:在Action类上边有一个以Map形式的集合压栈
方式三:获取值栈对象,调用值栈对象内的push方法
import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; @SuppressWarnings("serial") public class ValueStack1 extends ActionSupport { @Override public String execute() throws Exception { // 方式二:使用set方法 // 1.获取上下文 ActionContext ac = ActionContext.getContext(); // 2.获取值栈对象 ValueStack vs = ac.getValueStack(); // 3.使用set方法 vs.set("text", "测试文本"); // 4.使用push方法 vs.push("push测试文本"); return SUCCESS; } }
方式三执行结果:在Map上边有一个以push存储类型的形式压栈
- 值栈保存自定义对象/
5. 获取数据
- 操作值栈数据,使用<Iterator>标签 + OGNL表达式实现数据获取 (Struts2) <%@ taglib perfix="s" uri="/struts-tags"%>
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <body> <!-- 获取字符串 --> <%-- <s:property value="在值栈中的属性名(String类型)"/> --%> <hr> 获取对象: <br> <s:property value="user" /> <s:property value="user.username" /> <s:property value="user.password" /> <hr> <!-- 第一种方式 --> 方式一:<br> 获取集合: <s:property value="list" /> <br> 集合内的对象: <s:property value="list[0]" /> <br> 对象内的属性值:username = <s:property value="list[0].username" /> password = <s:property value="list[0].password" /> <br> <br> <%-- <s:iterator begin="遍历开始下标" end="遍历结束下标(包括当前值)" value="在值栈中的集合名称" var="集合被遍历后对象的别名" ></s:iterator> --%> <!-- 第二种方式 --> <!-- 使用Struts中的iterator标签 --> <!-- 执行结果是遍历所有对象 --> 方式二 - 1:<s:iterator value="list"> <br><s:iterator value="list"> 用户名:<s:property value="username" /> 密码:<s:property value="password" /><br> </s:iterator> <br> <!-- 执行结果是遍历范围内的对象 --> 方式二 - 2:<s:iterator begin="0" end="list.size()-2" value="list"><br> <s:iterator begin="0" end="list.size()-2" value="list"> 用户名:<s:property value="username" /> 密码:<s:property value="password" /><br> </s:iterator> <br><br> <!-- 第三种方式 --> <!-- 使用Iterator标签 --> 方式三:<s:iterator value="list" var="user"> + 符号:#<br> <s:iterator value="list" var="user"> 用户名:<s:property value="#user.username" /> 密码:<s:property value="#user.password" /><br> </s:iterator> <hr> <!-- 孤要来一个综合的--> 孤的测试:<s:iterator begin="0" end="1" value="list" var="user"> + 符号#<br> <s:iterator begin="0" end="1" value="list" var="user"> 用户名:<s:property value="#user.username"/> 密码:<s:property value="#user.password"/> </s:iterator> <!-- 调试 --> <s:debug /> </body> </html>
- 操作值栈数据,使用<foreach>标签 + EL表达式实现数据获取 (Web - JSP) <%@ taglib perfix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${list}" var="user"> ${user.username} ${user.password} </c:forEach>
× EL获取值栈内的数据的原理
- EL表达式获取域对象值
- 向域对象里面放置使用setAttribute方法,获取值使用getAttribute方法
- 底层增强request对象内的方法 - getAttribute方法
· 首先从request域获取值,如果获取到,直接返回
· 如果从request域获取不到值,便道值栈中把值获取出来,再将数据方法哦域对象中
以上是关于Struts2 进阶的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段