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>    
struts.xml
技术分享
<%@ 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>
HTMLCODE

  方式一:在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";
    }
}
ValueStack1 - GetCode

  方式一执行结果:该数据将被存储在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;
    }

}
ValueStack1 - SetCode

  方式二执行结果:在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;
    }

}
ValueStack1 - PushCode

  方式三执行结果:在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" />
    &nbsp;
    <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" />&nbsp;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" />&nbsp;密码:<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" />&nbsp;密码:<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" />&nbsp;密码:<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>
获取数据的页面代码 - OGNL

  - 操作值栈数据,使用<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获取值栈内的数据的原理
    - EL表达式获取域对象值
    - 向域对象里面放置使用setAttribute方法,获取值使用getAttribute方法
    - 底层增强request对象内的方法 - getAttribute方法
      · 首先从request域获取值,如果获取到,直接返回
      · 如果从request域获取不到值,便道值栈中把值获取出来,再将数据方法哦域对象中

    

































以上是关于Struts2 进阶的主要内容,如果未能解决你的问题,请参考以下文章

Struts2 进阶

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

Atom编辑器入门到精通 Atom使用进阶

我的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呢?(代码片段