1.添加依赖的Jar
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-rest-plugin</artifactId>
<version>2.1.6</version>
</dependency>
2.参数配置
// Action的类名以Controller为后缀
<constant name="struts.convention.action.suffix" value="Controller"/>
// Action中没有@Action注解也创建映射
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
// Action类所在的包
<constant name="struts.convention.action.packages" value="com.st.web"/>
// 搜索以web为结尾的包
<constant name="struts.convention.package.locators" value="web"/>
3.BaseController设计
package com.st.web;
import java.io.Serializable;
import org.apache.struts2.rest.HttpHeaders;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
public abstract class BaseController<T> implements ModelDriven<T>,
Serializable, Preparable {
private static final long serialVersionUID = 7449478681110941532L;
protected T entity;
/**
* GET: /{model}
*/
public abstract HttpHeaders index();
/**
* POST: /{model}
*/
public abstract HttpHeaders create();
/**
* PUT: /{model}/{id}
*/
public abstract String update();
/**
* DELETE: /{model}/{id}
*/
public abstract String destroy();
/**
* GET: /{model}/{id}
*/
public abstract HttpHeaders show();
/**
* GET: /{model}/{id}/edit
*/
public abstract String edit();
/**
* GET: /{model}/new
*/
public abstract String editNew();
@Override
public T getModel() {
return entity;
}
/**
* 子类通过重写此方法初始化实体类
*/
@Override
public abstract void prepare();
}
什么时候需要返回HttpHeaders?
当返回的给用户的响应需要 在http头部自定义一些内容 ,需要返回HttpHeaders的实现类。
官方文档原文:
The REST Plugin adds support for action methods that return HttpHeaders objects as a way for the action to have more control over the response. |
REST Plugin HttpHeaders的实现类DefaultHttpHeaders有哪些更多的控制?
String resultCode;
int status = SC_OK;
Object etag; //被请求变量的实体值
Object locationId;
String location; //
响应报头域用于重定向接受者到一个新的位置
boolean disableCaching; //
用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)
boolean noETag = false;
Date lastModified; //标记此文件在服务期端最后被修改的时间
|
Last-Modified和Etags如何帮助提高性能?
聪明的开发者会把Last-Modified 和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1. 客户端请求一个页面(A)。
2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。
聪明的开发者会把Last-Modified 和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1. 客户端请求一个页面(A)。
2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。
4.自定义的Controller
package com.st.web;
import java.util.Date;
import java.util.List;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import com.st.entity.User;
import com.st.service.UserService;
@Results( { @Result(name = "success", type = "redirectAction", params = {
"actionName", "user" }) })
public class UserController extends BaseController<User> {
private static final long serialVersionUID = -2697052455833496406L;
private UserService userService;
private List<User> list;
private Long id;
public HttpHeaders create() {
entity.setCreateTime(new Date());
userService.save(entity);
return new DefaultHttpHeaders("success");
}
public String destroy() {
userService.delete(entity.getId());
return "success";
}
public String edit() {
return "edit";
}
public String editNew() {
entity = new User();
return "editNew";
}
public HttpHeaders index() {
list = userService.list();
return new DefaultHttpHeaders("index").disableCaching();
}
public HttpHeaders show() {
return new DefaultHttpHeaders("show");
}
public String update() {
userService.save(entity);
return "success";
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public UserService getUserService() {
return userService;
}
@Override
public User getModel() {
return entity;
}
public void setId(Long id) {
if (null != id) {
System.out.println("id:" + id);
entity = userService.get(id);
} else {
this.id = id;
}
}
public Long getId() {
return id;
}
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
@Override
public void prepare() {
entity = new User();
}
}
5.View层
在WEB-INF\content目录下建立以下文件:user-edit.jsp,user-editNew.jsp,user-index.jsp。
user-index.jsp--以列表显示所有的User
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>User</title>
</head>
<body>
<a href="">List</a>
<a href="user/new">Add User</a>
<table border="0">
<tr>
<td width="100">Login Name</td>
<td width="120">Password</td>
<td width="100">Create Time</td>
<td width="80">Manage</td>
</tr>
<s:iterator value="list" id="u">
<tr>
<td><s:property value="#u.loginName"/></td>
<td><s:property value="#u.password"/></td>
<td><s:date format="yyyy-MM-dd HH:mm" name="#u.createTime"/></td>
<td>
<a href="user/${u.id }/edit">Edit</a>
<span>|</span>
<a href="user/${u.id}?_method=DELETE">Delete</a>
</td>
</tr>
</s:iterator>
</table>
</body>
</html>
user-editNew.jsp--创建新用户
<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>User</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<s:form action="%{#request.contextPath}/user" theme="simple" method="post">
<table>
<tr>
<td>Login Name:<s:textfield name="loginName"/></td>
</tr>
<tr>
<td>Password:<s:password name="password"/></td>
</tr>
<tr>
<td><s:submit value="Submit"/><s:reset value="Cancel" οnclick="history.back()"/></td>
</tr>
</table>
</s:form>
</body>
</html>
user-edit.jsp--编辑用户信息
<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>User</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<s:form action="%{#request.contextPath}/user/%{id}" theme="simple" method="post">
<s:hidden name="_method" value="put" />
<table>
<tr>
<td>ID:<s:textfield name="id" disabled="true"/></td>
</tr>
<tr>
<td>Login Name:<s:textfield name="loginName"/></td>
</tr>
<tr>
<td>Password:<s:password name="password"/></td>
</tr>
<tr>
<td><s:submit value="Submit"/><s:reset value="Cancel" οnclick="history.back()"/></td>
</tr>
</table>
</s:form>
</body>
</html>