Struts2 restful配置及使用
1.Struts2 restful配置及使用
前面介绍使用Maven构建Struts2时提到下载Struts2的GA完整版,解压后在apps目录里有struts2-rest-showcase.war这个示例,这里就以这个示例为例讲解一下Struts restful的用法。所有的内容在官方文档(.x/docs/convention-plugin.html,
.x/docs/rest-plugin.html)有详细讲解,我这里只是粗略过一下。
1.1在pom.xml添加rest依赖,如下所示:
<project xmlns=".0.0" xmlns:xsi=""
xsi:schemaLocation=".0.0 .xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.carson.demo</groupId>
<artifactId>struts2</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>struts2 Maven Webapp</name>
<url>;/url>
<!-- 属性配置 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<!-- struts2依赖包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.14</version>
</dependency>
<!-- struts restful 依赖包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.14</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-rest-plugin</artifactId>
<version>2.3.14</version>
</dependency>
<!-- log4j依赖包-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>struts2</finalName>
</build>
</project>
1.2在struts.xml添加rest plugin的配置,代码如下: <constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
".3.dtd">
<struts>
<constant name="struts.i18n.reload" value="false" />
<constant name="struts.devMode" value="false" />
<!-- struts2 restful -->
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<include file="struts-default.xml" />
</struts>
1.3 restful命名
rest返回结果的页面默认在WEB-INF/content目录下,它的风格是jsp页面的命名与控制层Action的命名一致,如Action为OrdersController,则jsp页面以orders-打头。这里强调下,整个Action的命名中除去Controller以外,只有首字母大写其他全部小写,否则会报错。
OrdersController.java
package com.carson.demo.action;
import java.util.Collection;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.convention.annotation.Result;
import com.carson.demo.model.Order;
import com.carson.demo.service.OrdersService;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Validateable;
import com.opensymphony.xwork2.ValidationAwareSupport;
@Results({
@Result(name="success", type="redirectAction", params = {"actionName" , "orders"})
})
public class OrdersController extends ValidationAwareSupport implements ModelDriven<Object>, Validateable{
private Order model = new Order();
private String id;
private Collection<Order> list;
private OrdersService ordersService = new OrdersService();
// GET /orders/1
public HttpHeaders show() {
return new DefaultHttpHeaders("show");
}
// GET /orders
public HttpHeaders index() {
list = ordersService.getAll();
return new DefaultHttpHeaders("index")
.disableCaching();
}
// GET /orders/1/edit
public String edit() {
return "edit";
}
// GET /orders/new
public String editNew() {
model = new Order();
return "editNew";
}
// GET /orders/1/deleteConfirm
public String deleteConfirm() {
return "deleteConfirm";
}
// DELETE /orders/1
public String destroy() {
ordersService.remove(id);
addActionMessage("Order removed successfully");
return "success";
}
// POST /orders
public HttpHeaders create() {
ordersService.save(model);
addActionMessage("New order created successfully");
return new DefaultHttpHeaders("success")
.setLocationId(model.getId());
}
// PUT /orders/1
public String update() {
ordersService.save(model);
addActionMessage("Order updated successfully");
return "success";
}
public void validate() {
if (model.getClientName() == null || model.getClientName().length() ==0) {
addFieldError("clientName", "The client name is empty");
}
}
public void setId(String id) {
if (id != null) {
this.model = ordersService.get(id);
}
this.id = id;
}
public Object getModel() {
return (list != null ? list : model);
}
}
Orders.java
package com.carson.demo.model;
public class Order {
String id;
String clientName;
int amount;
public Order() {}
public Order(String id, String clientName, int amount) {
super();
this.id = id;
this.clientName = clientName;
this.amount = amount;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + amount;
result = prime * result
+ ((clientName == null) ? 0 : clientName.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Order other = (Order) obj;
if (amount != other.amount)
return false;
if (clientName == null) {
if (other.clientName != null)
return false;
} else if (!clientName.equals(other.clientName))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
OrdersService.java
package com.carson.demo.service;
import java.util.*;
import com.carson.demo.model.Order;
public class OrdersService {
private static Map<String,Order> orders = new HashMap<String,Order>();
private static int nextId = 6;
static {
orders.put("3", new Order("3", "Bob", 33));
orders.put("4", new Order("4", "Sarah", 44));
orders.put("5", new Order("5", "Jim", 66));
}
public Order get(String id) {
return orders.get(id);
}
public List<Order> getAll() {
return new ArrayList<Order>(orders.values());
}
public void save(Order order) {
if (order.getId() == null) {
order.setId(String.valueOf(nextId++));
}
orders.put(order.getId(), order);
}
public void remove(String id) {
orders.remove(id);
}
}
order-index.jsp
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 Transitional//EN"
".dtd">
<%@taglib prefix="s" uri="/struts-tags" %>
<html xmlns="" xml:lang="en" lang="en">
<head>
<title>Orders</title>
</head>
<body>
<s:actionmessage />
<table>
<tr>
<th>ID</th>
<th>Client</th>
<th>Amount</th>
<th>Actions</th>
</tr>
<s:iterator value="model">
<tr>
<td>${id}</td>
<td><s:property value="clientName"/></td>
<td><s:property value="amount"/></td>
<td><a href="orders/${id}">View</a> |
<a href="orders/${id}/edit">Edit</a> |
<a href="orders/${id}/deleteConfirm">Delete</a></td>
</tr>
</s:iterator>
</table>
<a href="orders/new">Create a new order</a>
</body>
</html>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
".dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<init-param>
<param-name>config</param-name>
<!-- <param-value>../../resources/struts.xml</param-value> -->
<param-value>classpath:struts.xml</param-value>
</init-param>
<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>
<!-- log4j -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
先介绍这么多,后续有时间继续补充。