Struts学习(三)-OGNL(Object-Graph Navigation Language),异常处理

OGNL

在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性.

若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #, 搜索将在 ObjectStack 里进行.

property 标签

Struts 的 property 标签用来输出值栈中的一个属性值.


读取 ObjectStack 里的对象的属性

若想访问 Object Stack 里的某个对象的属性. 可以使用以下几种形式之一: ObjectStack 里的对象可以通过一个从零开始的下标来引用.

ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用.

若希望返回栈顶对象的 message 属性值: [0].message 或 [0][“message”] 或 [0][‘message’]

若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索.

即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象 若从栈顶对象开始搜索, 则可以省略下标部分

读取 Context Map 里的对象的属性

若想访问 ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:

示例: 返回 session 中的 code 属性: #session.code

返回 request 中的 customer 属性的 name 属性值: #request.customer.name

返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性: #attr.lastAccessDate

 

调用字段和方法

可以利用 OGNL 调用 任何一个 Java 类里的静态字段或方法. 被压入到 ValueStack 栈的对象上的公共字段和方法.

默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.

调用静态字段或方法需要使用如下所示的语法: @fullyQualifiedClassName@fieldName: @java.util.Calendar@DECEMBER @fullyQualifiedClassName@methodName(argumentList): @app4.Util@now()

调用一个实例字段或方法的语法, 其中 object 是 Object Stack 栈里的某个对象的引用:

.object.fieldName: [0].datePattern .object.methodName(argumentList): [0].repeat(3, “Hello”);

访问数组类型的属性

 

有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们.

这种数组型属性的各个元素以逗号分隔, 并且不带方括号

可以使用下标访问数组中指定的元素: colors[0] 可以通过调用其 length 字段查出给定数组中有多少个元素: colors.length

 

访问 List 类型的属性

有些属性将返回的类型是 java.util.List, 可以像读取任何其他属性那样读取它们.

这种 List 的各个元素是字符串, 以逗号分隔, 并且带方括号

可以使用下标访问 List 中指定的元素: colors[0] 可以通过调用其 size 方法或专用关键字 size 的方法查出给定List 的长度: colors.size 或 colors.size()

可以通过使用 isEmpty() 方法或专用关键字 isEmpty 来得知给定的 List 是不是空. colors.isEmpty 或 colors.isEmpty() 还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的: {“Red”, “Black”, “Green”}

 访问 Map 类型的属性

读取一个 Map 类型的属性将以如下所示的格式返回它所有的键值对:

若希望检索出某个 Map 的值, 需要使用如下格式: map[key] 可以使用 size 或 size() 得出某个给定的 Map 的键值对的个数

可以使用 isEmpty 或 isEmpty() 检查某给定 Map 是不是空. 可以使用如下语法来创建一个 Map:

 使用 EL 访问值栈中对象的属性

<s:property value=“fieldName”> 也可以通过 JSP EL 来达到目的:

${fieldName} 原理: Struts2 将包装 HttpServletRequest 对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 对象传到页面上, 而这个类重写了 getAttribute() 方法.

异常处理: exception-mapping 元素

exception-mapping 元素: 配置当前 action 的声明式异常处理 exception-mapping 元素中有 2 个属性 exception: 指定需要捕获的的异常类型。

异常的全类名 result: 指定一个响应结果, 该结果将在捕获到指定异常时被执行, 既可以来自当前 action 的声明, 也可以来自 global-results 声明. 可以通过 global-exception-mappings 元素为应用程序提供一个全局性的异常捕获映射.

但在 global-exception-mappings 元素下声明的任何 exception-mapping 元素只能引用在 global-results 元素下声明的某个 result 元素 声明式异常处理机制由 ExceptionMappingInterceptor 拦截器负责处理, 当某个 exception-mapping 元素声明的异常被捕获到时, ExceptionMappingInterceptor 拦截器就会向 ValueStack 中添加两个对象: exception: 表示被捕获异常的 Exception 对象 exceptionStack: 包含着被捕获异常的栈 可以在视图上通过 <s:property> 标签显示异常消息

 实例

 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

  <a href="product-input.action">product-input</a>
  
</body>
</html>

input.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>


<s:debug></s:debug>
<!-- 
<s:property value="exceptionStack"/>
<br>
 -->
<s:property value="exception"/>-
${exception }
<s:property value="exception.message"/>-
${exception.message }
<br><br><br>

<form action="product-save.action" method="post">
      
      ProductName:<input type="text" name="productName"/>
      <br><br>
      
      ProductDesc:<input type="text" name="productDesc"/>
      <br><br>
      
      ProductPrice:<input type="text" name="productPrice"/>
      <br><br>
      <input type="submit" name="Submit"/>
      <br><br>
</form>
</body>
</html>

details.jsp

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <s:debug></s:debug>

    ProductName:${productName}
    <br>
    <br> ProductName1:
    <s:property value="[1].productName" />
    <br>
    <br> ProductName2:${sessionScope.product.productName}
    <s:property value="#session.product.productName" />
    <br>
    <br>

    <br>
    <br> ProductDesc:${productDesc}
    <br>
    <br> ProductPrice:${productPrice}
    <br>
    <br> ProductPrice*:
    <s:property value="[0].productPrice" />
    <br>
    <br> productPrice**:
    <s:property value="productPrice" />
    <br>
    <br>
    <!-- 使用OGNL调用public类的public类型的静态字段和静态方法 -->
    <s:property value="@java.lang.Math@PI" />
    <br>
    <br>
    <s:property value="@java.lang.Math@cos(0)" />
    <!-- 调用对象栈的方法为一个属性赋值 -->
    <br>
    <br>
    <s:property value="setProductName('yuyiiiii')" />
    <br>
    <br>
    <s:property value="productName" />
    <!-- 调用数组对象的属性 -->
    <%
           int[] number=new int[]{1,2,3,4,5};
           request.setAttribute("number", number);
         %>
    <br>
    <br>
    length:<s:property value="#attr.number.length" />
    <br>
    <br>
    number[2]:<s:property value="#attr.number[2]"/>
    <br><br>
    <%
    Map<String,String> letter=new HashMap<String,String>();
    request.setAttribute("letter", letter);
    
    letter.put("AA", "a");
    letter.put("BB", "b");
    letter.put("CC", "c");
    %>
    <!-- 使用OGNL访问Map -->
    Size:<s:property value="#attr.letter.size"/>
    <br><br>
    AA:<s:property value="#attr.letter['AA']"/>
</body>
</html>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

<!-- 打开静态方法调用的限制 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<!-- 配置Struts可以受理的请求的扩展名 -->
<constant name="struts.action.extension" value="action,do"></constant>

  <package name="default"  extends="struts-default">
  
    <action name="product-input">
     <result>/input.jsp</result>
    </action>
    
    <action name="product-save" class="com.yuyi.struts.valueStack.Product"  method="save">
    
     <exception-mapping result="input" exception="java.lang.ArithmeticException"></exception-mapping>
     <result name="input">/input.jsp</result>
     
     <result name="details">/details.jsp</result>
    </action>
  </package>
   
</struts>

Product.java

package com.yuyi.struts.valueStack;

import java.util.Map;

import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;

public class Product implements RequestAware,SessionAware{

    private Integer productId;
    private String productName;
    private String productDesc;
    private double productPrice;

    public Integer getProductId() {
        return productId;
    }
    public void setProductId(Integer productId) {
        this.productId = productId;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getProductDesc() {
        return productDesc;
    }
    public void setProductDesc(String productDesc) {
        this.productDesc = productDesc;
    }
    public double getProductPrice() {
        return productPrice;
    }
    public void setProductPrice(double productPrice) {
        this.productPrice = productPrice;
    }
    @Override
    public String toString() {
        return "Product [productId=" + productId + ", productName=" + productName + ", productDesc=" + productDesc
                + ", productPrice=" + productPrice + "]";
    }
    
    public String save() {
        System.out.println("save:"+this);
        
        //1.获取值栈
        ValueStack valueStack=ActionContext.getContext().getValueStack();
        //2.创建Test对象,并为其属性赋值
        Test object=new Test();
        object.setProductName("AABBCC");
        object.setProductDesc("AABBCCDD");
        //3.把Test对象压入值栈的栈顶
        valueStack.push(object);
        
        session.put("product", this);
        request.put("test", object);
        
        int i=10/0;
        
        return "details";
    }
    private Map<String, Object> session;
    @Override
    public void setSession(Map<String, Object> arg0) {
        this.session=arg0;
        
    }
    private Map<String, Object> request;
    @Override
    public void setRequest(Map<String, Object> arg0) {
        this.request=arg0;
        
    }
}

 Test.java

package com.yuyi.struts.valueStack;

public class Test {
    private String productName;
    private String productDesc;
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getProductDesc() {
        return productDesc;
    }
    public void setProductDesc(String productDesc) {
        this.productDesc = productDesc;
    }
}

猜你喜欢

转载自www.cnblogs.com/yuyiWang/p/9568722.html