struts2 ognl_Struts2 OGNL

struts2 ognl

Struts2 OGNL is the expression language where OGNL stands for Object-Graph Navigation Language. OGNL is tightly coupled in Struts2 and used to store form parameters as java bean variables in ValueStack and to retrieve the values from ValueStack in result pages.

Struts2 OGNL是表达语言,其中OGNL表示对象图导航语言 。 OGNL与Struts2紧密耦合,用于将表单参数作为Java Bean变量存储在ValueStack中,并在结果页中从ValueStack检索值。

Struts2 OGNL (Struts2 OGNL)

Struts2 OGNL performs two important tasks – data transfer and type conversion.

Struts2 OGNL执行两项重要任务- 数据传输类型转换

OGNL in Struts2 takes the request parameters from the servlet request and transfer it to corresponding java variable.

Struts2中的OGNL从servlet请求中获取请求参数,并将其传输到相应的java变量。

Since we get request params as String but java bean variables can be String, int, array, list or any custom object, type conversion is also an important task and OGNL takes care of type conversion through it’s built-in type converters.

由于我们将请求参数作为String来获取,而java bean变量可以是String,int,数组,列表或任何自定义对象,因此类型转换也是一项重要任务,OGNL会通过其内置的类型转换器来处理类型转换。

Struts2 OGNL is flexible and we can easily extend it to create our own custom converter class. We will first look into the OGNL usage with basic data types such as String, boolean, int, arrays and lists. Then we will create our own converter class for a custom java bean variable.

Struts2 OGNL非常灵活,我们可以轻松地对其进行扩展以创建我们自己的自定义转换器类。 我们将首先使用基本数据类型(例如String,boolean,int,数组和列表)来研究OGNL的用法。 然后,我们将为自定义java bean变量创建自己的转换器类。

Struts2 OGNL示例 (Struts2 OGNL Example)

Our final project structure for Struts2 OGNL example looks like below image.

我们针对Struts2 OGNL示例的最终项目结构如下图所示。

Struts 2配置文件 (Struts 2 Configuration Files)

web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns="https://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>Struts2OGNLExample</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

pom.xml

pom.xml

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Struts2OGNLExample</groupId>
	<artifactId>Struts2OGNLExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.15.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

struts.xml

struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"https://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="false"></constant>
<constant name="struts.convention.result.path" value="/"></constant>
<package name="user" namespace="/" extends="struts-default">
	<action name="home">
		<result>/home.jsp</result>
	</action>
	<action name="welcome" class="com.journaldev.struts2.actions.WelcomeAction">
	<result name="success">/welcome.jsp</result>
	</action>

</package>

</struts>

Configuration files are self understood and they are just to configure our application to use Struts 2 framework.

配置文件是易于理解的,它们只是为了配置我们的应用程序以使用Struts 2框架。

Struts2 OGNL示例模型类 (Struts2 OGNL Example Model Classes)

package com.journaldev.struts2.model;

public class Data {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
}
package com.journaldev.struts2.model;

public class Rectangle {

	private int x;
	private int y;
	
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	
	
}
package com.journaldev.struts2.model;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class MyJavaBean {

	private String name;
	private boolean flag;
	private Integer age;
	private Date date;
	private String[] stocks;
	//roles array needs to initialize because it's used with index in form
	private String[] roles = new String[5];
	
	//do not preinitialize lists or any collections
	private List<Data> usersList;
	private List<Data> fruitsList;
	private Map<String, Data> usersMap;
	
	//custom type converter example
	private Rectangle rectangle;
	
	public List<Data> getFruitsList() {
		return fruitsList;
	}
	public void setFruitsList(List<Data> fruitsList) {
		this.fruitsList = fruitsList;
	}
	public List<Data> getUsersList() {
		return usersList;
	}
	public void setUsersList(List<Data> users) {
		this.usersList = users;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public String[] getStocks() {
		return stocks;
	}
	public void setStocks(String[] stocks) {
		this.stocks = stocks;
	}
	public String[] getRoles() {
		return roles;
	}
	public void setRoles(String[] roles) {
		this.roles = roles;
	}
	public Map<String, Data> getUsersMap() {
		return usersMap;
	}
	public void setUsersMap(Map<String, Data> usersMap) {
		this.usersMap = usersMap;
	}
	public Rectangle getRectangle() {
		return rectangle;
	}
	public void setRectangle(Rectangle rectangle) {
		this.rectangle = rectangle;
	}
	
}

MyJavaBean is the action bean class that we will use, notice the variable of type Rectangle. Since it’s a custom class, we need to implement our own converter class for this. We will look into this later.

MyJavaBean是我们将使用的动作bean类,请注意Rectangle类型的变量。 由于它是一个自定义类,因此我们需要为此实现自己的转换器类。 我们稍后将对此进行研究。

Struts2 OGNL示例动作类 (Struts2 OGNL Example Action Class)

package com.journaldev.struts2.actions;

import com.journaldev.struts2.model.MyJavaBean;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class WelcomeAction extends ActionSupport implements ModelDriven<MyJavaBean>{

	public String execute(){
		return SUCCESS;
	}
	
	private MyJavaBean bean = new MyJavaBean();
	
	@Override
	public MyJavaBean getModel() {
		return bean;
	}

}

Action class just returns the success page, there is no logic done here.

动作类仅返回成功页面,此处没有逻辑。

Struts2 OGNL示例结果页面 (Struts2 OGNL Example Result Pages)

home.jsp

home.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Home Page Form</title>
</head>
<body>
<h3>Struts 2 OGNL Examples</h3>
<s:form action="welcome" method="post">
<table>
<s:textfield name="name" label="Name" ></s:textfield>
<s:textfield name="flag" label="True/False?"></s:textfield>
<s:textfield name="age" label="Current Year?"></s:textfield>
<s:textfield name="date" label="Todays Date (mm/dd/yyyy)?"></s:textfield>
</table>
<h3>Struts 2 Array OGNL Example</h3>

<strong>Array with same name example</strong><br>
<table>
<s:textfield name="stocks" label="Stock 1"></s:textfield>
<s:textfield name="stocks" label="Stock 2"></s:textfield>
<s:textfield name="stocks" label="Stock 3"></s:textfield>
</table>

<strong>Array with indexed name example</strong><br>
<table>
<s:textfield name="roles[0]" label="Role 1"></s:textfield>
<s:textfield name="roles[1]" label="Role 2"></s:textfield>
<s:textfield name="roles[2]" label="Role 3"></s:textfield>
</table>

<h3>Struts 2 List OGNL Example</h3>

<strong>List with same name example</strong><br>
<table>
<s:textfield name="usersList.name" label="User 1 Name"></s:textfield>
<s:textfield name="usersList.name" label="User 2 Name"></s:textfield>
<s:textfield name="usersList.name" label="User 3 Name"></s:textfield>
</table>
<strong>List with indexed name example</strong><br>
<table>
<s:textfield name="fruitsList[0].name" label="Fruit 1"></s:textfield>
<s:textfield name="fruitsList[1].name" label="Fruit 2"></s:textfield>
<s:textfield name="fruitsList[2].name" label="Fruit 3"></s:textfield>
</table>

<strong>Map Example</strong>
<table>
<s:textfield name="usersMap['first'].name" label="User 1"></s:textfield>
<s:textfield name="usersMap['second'].name" label="User 2"></s:textfield>
<s:textfield name="usersMap['third'].name" label="User 3"></s:textfield>
</table>

<strong>Custom Converter Example</strong>
<table>
<s:textfield name="rectangle" label="Rectangle in format R:x,y"></s:textfield>
</table>
<s:submit label="Submit" align="left"></s:submit>
</s:form>
</body>
</html>

home.jsp is used as input page where user can provide values and invoke welcome action.

home.jsp用作输入页面,用户可以在其中提供值并调用欢迎操作。

welcome.jsp

welcome.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Welcome Page Example</title>
</head>
<body>
<h3>Struts 2 OGNL Examples</h3>
Name = <s:property value="name"></s:property><br>
True/False? = <s:property value="flag" ></s:property><br>
Current Year? = <s:property value="age"></s:property><br>
Todays Date (mm/dd/yyyy)? = <s:date name="date" format="MM/dd/yyyy"></s:date><br><br>

Stocks Array = <s:property value="stocks"/><br>
Roles Array = <s:property value="roles"/><br><br>
Users List = <s:iterator value="usersList"><s:property value="name"/>  </s:iterator><br>
Fruits List = <s:iterator value="fruitsList"><s:property value="name"/>  </s:iterator><br>
Fruit 1 Name = <s:property value="fruitsList[0].name"/><br><br>

Users Map = <s:iterator value="usersMap">{<s:property value="key"/>,<s:property value="value.name"/>}  </s:iterator><br><br>

Rectangle Dimensions: x = <s:property value="rectangle.x"/> and y = <s:property value="rectangle.y"/><br>
</body>
</html>

welcome.jsp is just used to show the values used by the user as a proof that OGNL is taking care of data transfer as well as type conversion.

welcome.jsp仅用于显示用户使用的值,以证明OGNL正在处理数据传输和类型转换。

Before we move on to discuss on custom converter classes, let’s look at some important points in above implementation.

在继续讨论自定义转换器类之前,让我们看一下上述实现中的一些要点。

  1. Basic data types conversion is automatic, we don’t need to follow any special rules for them.

    基本数据类型转换是自动的,我们不需要遵循任何特殊规则。
  2. Struts 2 takes care of converting String to Date also and we can use s:date to display it with specific format.

    Struts 2还负责将String转换为Date,我们可以使用s:date以特定格式显示它。
  3. Arrays and Lists can be used with name as well as index. If we use index, then we need to initialize the array in the bean. That’s why roles array is initialized in the bean class.

    数组和列表可以与名称以及索引一起使用。 如果使用索引,则需要在bean中初始化数组。 这就是为什么在bean类中初始化角色数组的原因。
  4. Do not initialize the list variables in bean else it will throw error. OGNL takes care of initialization and populating values.

    不要在bean中初始化列表变量,否则会抛出错误。 OGNL负责初始化和填充值。
  5. OGNL in Struts2 also provides built-in support for Map that we can use in result pages.

    Struts2中的OGNL还提供了对Map的内置支持,我们可以在结果页中使用它。
  6. We can use iterator with multi-values data types such as List, Map, Array to traverse through them. We can use index or key to get specific values from these variables.

    我们可以将迭代器与List,Map,Array等多值数据类型一起使用来遍历它们。 我们可以使用索引或键从这些变量中获取特定值。

Struts2 OGNL自定义类型转换器 (Struts2 OGNL Custom Type Converter)

Creating and configuring custom type converter class is very easy. First step is to fix the input format for the custom class. For my example, I have fixed the user input to be R:x,y where x and y are rectangle variables and should be integers.

创建和配置自定义类型转换器类非常容易。 第一步是修复自定义类的输入格式。 对于我的示例,我已将用户输入固定为R:x,y ,其中x和y是矩形变量,应为整数。

Second step is to implement the converter class. Type converter classes should implement com.opensymphony.xwork2.conversion.TypeConverter interface.

第二步是实现转换器类。 类型转换器类应实现com.opensymphony.xwork2.conversion.TypeConverter接口。

Since in web application, we always get the request in form of String and send response in the form of String, Struts 2 API provides a default implementation of TypeConverter interface, StrutsTypeConverter.

由于在Web应用程序中,我们总是以String形式获取请求,并以String形式发送响应,因此Struts 2 API提供了TypeConverter接口的默认实现StrutsTypeConverter

StrutsTypeConverter contains two abstract methods – convertFromString to convert String to Object and convertToString to convert Object to String. We will extend this class for custom type converter.

StrutsTypeConverter包含两个抽象方法– convertFromString将String转换为Object, convertToString将Object转换为String。 我们将为自定义类型转换器扩展此类。

package com.journaldev.struts2.typeconverters;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

import com.journaldev.struts2.model.Rectangle;
import com.opensymphony.xwork2.conversion.TypeConversionException;

/**
 * Custom type converter to convert user input to Rectangle
 * Format is R:x,y where x and y are int defining Rectangle dimensions 
 * @author pankaj
 *
 */
public class RectangleTypeConverter extends StrutsTypeConverter {

	@Override
	public Object convertFromString(Map arg0, String[] inputs, Class arg2) {
		String input = inputs[0];
		if(!input.startsWith("R:")) throw new TypeConversionException("invalid input");
		input = input.substring(2);
		String[] dimensions = input.split(",");
		int x = Integer.parseInt(dimensions[0]);
		int y = Integer.parseInt(dimensions[1]);
		Rectangle rect = new Rectangle();
		rect.setX(x);
		rect.setY(y);
		return rect;
	}

	@Override
	public String convertToString(Map arg0, Object obj) {
		Rectangle rect = (Rectangle) obj;
		String output = "R:" + rect.getX() + "," + rect.getY();
		return output;
	}

}

Notice that code is very simple and parse input string to object and vice versa.

请注意,代码非常简单,可以将输入字符串解析为对象,反之亦然。

Next step is to configure the type converter to be used for Rectangle type variables. There are two ways to configure this – first is to configure for specific action and second way is to configure globally.

下一步是配置要用于Rectangle类型变量的类型转换器。 有两种配置方式–第一种是针对特定操作进行配置,第二种方式是进行全局配置。

For action specific converter, we can use com.opensymphony.xwork2.conversion.annotations.TypeConversion annotation and change the setter method like below.

对于特定于动作的转换器,我们可以使用com.opensymphony.xwork2.conversion.annotations.TypeConversion注释并更改设置方法,如下所示。

@TypeConversion(converter="com.journaldev.struts2.typeconverters.RectangleTypeConverter")
public void setRectangle(Rectangle rectangle) {
	this.rectangle = rectangle;
}

用于ModelDriven动作类的自定义类型转换器 (Custom Type Converter for ModelDriven Action Classes)

If Action class is implementing ModelDriven interface for java bean, another way is to create property file with name as {JavaBeanName}-conversion.properties and put it in the same package as java bean class, so we can create MyJavaBean-conversion.properties and put it in com.journaldev.struts2.model package with below data.

如果Action类正在为Java bean实现ModelDriven接口,则另一种方法是创建名称为{JavaBeanName} -conversion.properties的属性文件,并将其放入与Java bean类相同的包中,因此我们可以创建MyJavaBean-conversion.properties和将其com.journaldev.struts2.model带有以下数据的com.journaldev.struts2.model程序包中。

MyJavaBean-conversion.properties

MyJavaBean-conversion.properties

#For Action Classes implementing ModelDriven<MyJavaBean>
#variable-name=TypeConverter class name
rectangle=com.journaldev.struts2.typeconverters.RectangleTypeConverter

For global conversion, as I have done in this project, we need to create xwork-conversion.properties properties file and make sure it’s in WEB-INF/classes directory. We need to provide the class name and converter as key-value pair. For us it’s

对于全局转换,正如我在该项目中所做的那样,我们需要创建xwork-conversion.properties属性文件,并确保它位于WEB-INF / classes目录中。 我们需要提供类名和转换器作为键值对。 对我们来说

xwork-conversion.properties

xwork-conversion.properties

#Application level custom converter configuration
com.journaldev.struts2.model.Rectangle=com.journaldev.struts2.typeconverters.RectangleTypeConverter

Now when we will run our application, we will get following response pages.

Struts2 OGNL Custom Type Converter Input

现在,当我们运行我们的应用程序时,我们将获得以下响应页面。

That’s all for Struts2 OGNL example tutorial, I hope you liked it. Download project from below link and run yourself.

这就是Struts2 OGNL示例教程的全部内容,希望您喜欢它。 从下面的链接下载项目并自己运行。

翻译自: https://www.journaldev.com/2221/struts2-ognl

struts2 ognl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值