从上面粗体字代码可以看出,BookService 提供了 4 个方法,用于实现对 Book 对象的 CRUD 操作。
下面开始定义支持 REST 的 Action 类了,这个 Action 类与前面介绍 Struts 2 的普通 Action
存在一些差异——因为该 Action 不再用 execute() 方法来处理用户请求,而是使用前面介绍的 7
个标准方法来处理用户请求。除此之外,该 Action 总是需要处理 id 请求参数,因此必须提供 id 请求参数,并为之提供对应的 setter
和 getter 方法。
因为本系统已经提供了 Book Model 类,并且为了更好的模拟 Rails 中
ActiveController(Controller)直接访问 ActiveRecord(Model)的方式,本系统采用了
ModelDriven 的开发方式,下面是本系统中支持 REST 的 Action 类的代码。
// 定义返回 success 时重定向到 book Action
@Results(@Result(name="success"
, type="redirectAction"
, params = {"actionName" , "book"}))
public class BookController extends ActionSupport
implements ModelDriven<Object>
{
// 封装 id 请求参数的属性
private int id;
private Book model = new Book();
private List<Book> list;
// 定义业务逻辑组件
private BookService bookService = new BookService();
// 获取 id 请求参数的方法
public void setId(int id)
{
this.id = id;
// 取得方法时顺带初始化 model 对象
if (id > 0)
{
this.model = bookService.get(id);
}
}
public int getId()
{
return this.id;
}
// 处理不带 id 参数的 GET 请求
// 进入首页
public HttpHeaders index()
{
list = bookService.getAll();
return new DefaultHttpHeaders("index")
.disableCaching();
}
// 处理不带 id 参数的 GET 请求
// 进入添加新图书。
public String editNew()
{
// 创建一个新图书
model = new Book();
return "editNew";
}
// 处理不带 id 参数的 POST 请求
// 保存新图书
public HttpHeaders create()
{
// 保存图书
bookService.saveOrUpdate(model);
addActionMessage("添加图书成功");
return new DefaultHttpHeaders("success")
.setLocationId(model.getId());
}
// 处理带 id 参数的 GET 请求
// 显示指定图书
public HttpHeaders show()
{
return new DefaultHttpHeaders("show");
}
// 处理带 id 参数、且指定操作 edit 资源的 GET 请求
// 进入编辑页面 (book-edit.jsp)
public String edit()
{
return "edit";
}
// 处理带 id 参数的 PUT 请求
// 修改图书
public String update()
{
bookService.saveOrUpdate(model);
addActionMessage("图书编辑成功!");
return "success";
}
// 处理带 id 参数,且指定操作 deleteConfirm 资源的方法
// 进入删除页面 (book-deleteConfirm.jsp)
public String deleteConfirm()
{
return "deleteConfirm";
}
// 处理带 id 参数的 DELETE 请求
// 删除图书
public String destroy()
{
bookService.remove(id);
addActionMessage("成功删除 ID 为" + id + "的图书!");
return "success";
}
// 实现 ModelDriven 接口必须实现的 getModel 方法
public Object getModel()
{
return (list != null ? list : model);
}
}
|
上面 Action 代码中粗体字代码定义了 7 个方法,这 7 个方法正是前面提到的标准方法。除此之外,该 Action
里还包含一个额外的 deleteConfirm() 方法,这个方法用于处理带 id 参数、且指定操作 deleteConfirm 资源的 GET
请求。也就是说,当用户请求 /book/1/deleteConfirm 时,该请求将由该方法负责处理。
实际上,RestActionMapper 不仅可以将对 /book/1/edit 的请求映射到 Book 控制器的 edit() 方法,而
1 将作为 id 请求参数。实际上,它可以将任意 /book/1/xxx 的请求映射到 Book 控制器的 xxx() 方法,而 1
是请求参数。
上面 Action 类使用了 @Results 进行修饰,这表明当 Action
的任何方法返回“success”逻辑视图时,系统将重定向到 book.action。
可能有读者会对 index()、create()、show()
三个方法的返回值感到疑惑:它们不再直接返回普通字符串作为逻辑视图名字,而是返回一个以字符串为参数的 DefaultHttpHeaders
对象?其实读者不必对 DefaultHttpHeaders 感到疑惑,其实 DefaultHttpHeaders 只是普通字符串的加强形式,用于
REST 对处理结果进行更多额外的控制。
当 Action 类的处理方法返回字符串作为逻辑视图时,Struts 2
只能将其当成一个简单的视图名,仅能根据该视图名映射到实际视图资源,仅此而已。如果使用 DefaultHttpHeaders
作为逻辑视图,DefaultHttpHeaders 除了可以包含普通字符串作为逻辑视图名之外,还可以额外增加更多的控制数据,从而可以增强对
Response 的控制。关于 HttpHeaders 和 DefaultHttpHeaders 的介绍请参考 REST 插件的 API。
还有一点需要指出,上面的 BookController 控制器实现类的类名并不以 Action 结尾,而是以 Controller
结尾,因此我们可以在 struts.xml 文件中配置如下常量:
<!-- 指定控制器类的后缀为 Controller -->
<constant name="struts.convention.action.suffix"
value="Controller"/>
本应用里的 struts.xml 文件如下:
程序清单:codes\12\12.6\BookShow\WEB-INF\src\struts.xml
<?xml version="1.0" encoding="GBK" ?>
<!-- 指定 Struts 2 配置文件的 DTD 信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<!-- 指定 Struts 2 配置文件的根元素 -->
<struts>
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 指定控制器类的后缀为 Controller -->
<constant name="struts.convention.action.suffix"
value="Controller"/>
<constant name="struts.convention.action.mapAllMatches"
value="true"/>
<!-- 指定 Action 所在包继承的父包 -->
<constant name="struts.convention.default.parent.package"
value="rest-default"/>
</struts>
|
实现视图层
定义了上面 Action 之后,接下来应该为这些 Action 提供视图页面了,根据 Convention
插件的约定,所有视图页面都应该放在 WEB-INF\content 目录下,例如当用户向 /book.action 发送请求时,该请求将由
BookController 的 index() 方法进行处理,该方法处理结束后返回“index”字符串,也就是将会使用
WEIN-INF\content\book-index.jsp 页面作为视图资源。下面是 book-index.jsp 页面的代码:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 图书展示系统 </title>
<link href="<%=request.getContextPath() %>/css/demo.css"
rel="stylesheet" type="text/css" />
</head>
<body>
<s:actionmessage />
<table>
<tr>
<th> 图书 ID</th>
<th> 书名 </th>
<th> 价格 </th>
<th> 操作 </th>
</tr>
<s:iterator value="model">
<tr>
<td><s:property value="id"/></td>
<td>${name}</td>
<td>${price}</td>
<td><a href="book/${id}"> 查看 </a> |
<a href="book/${id}/edit"> 编辑 </a> |
<a href="book/${id}/deleteConfirm"> 删除 </a></td>
</tr>
</s:iterator>
</table>
<a href="<%=request.getContextPath() %>/book/new"> 创建新图书 </a>
</body>
</html>
|
上面 JSP 页面非常简单,它负责迭代输出 Action 里包含的集合数据,向该应用 book.action 发送请求将看到如图 1
所示页面。
图 1 使用 Struts 2 开发的 REST 服务
Struts 2 的 REST 插件支持一种资源具有多少表示形式,当浏览者向 book.xml 发送请求将可以看到如图 2 所示页面。
图 2 REST 服务的 XML 形式
从图 2 可以看出,该页面正是 Action 所包含的全部数据,当使用 XML 显示时 REST 插件将会负责把这些数据转换成 XML
文档。
除此之外,REST 插件还提供了 JSON 格式的显示方式,当开发者向 book.json 发送请求将看到如图 3 所示页面。
图 3 REST 服务的 JSON 形式
Struts 2 的 REST 插件默认支持 XHTML、XML 和 JSON 三种形式的数据。
分享到:
相关推荐
RESTful开发是现代Web服务开发的核心技术之一,尤其在API设计中广泛应用。 1. RESTful原则: - 客户端-服务器架构:客户端与服务器之间无状态,每个请求包含所有必要的信息。 - 统一接口:包括资源识别(通过URI...
描述中的“SAP BO restful开发文档说明”暗示文档将深入讲解如何配置和使用这些接口,以及如何在实际项目中实施RESTful服务。这可能包括请求方法(GET、POST、PUT、DELETE等)、资源的URI设计、数据格式(如JSON或...
总结来说,Spring Data REST 通过以下方式简化了 RESTful API 的开发: 1. 自动将 Repository 接口转换为 RESTful 资源,无需编写额外的 Controller 代码。 2. 提供了对多种数据存储的支持,包括 JPA、MongoDB 等。...
本项目旨在教你如何使用Flask和Flask-Restful开发REST风格的接口,并利用蓝图(Blueprints)提高代码的可维护性和扩展性。 首先,让我们了解REST(Representational State Transfer)风格。REST是一种网络应用程序...
在IT行业中,Python3语言因其简洁明了的语法和丰富的库支持,被广泛应用于Web开发,尤其是构建RESTful API服务。本项目旨在介绍如何利用Python3、Django2.0框架、Django REST Framework(DRF)、CentOS7操作系统、...
**RESTful(Representational State Transfer)是Web服务的一种设计风格,它强调了资源的重要性,并通过HTTP协议中的方法来操作这些资源。...深入研究和实践CXF的RESTful开发,对于提升Java Web开发技能大有裨益。
10. **版本控制**:项目文件名为"quanDeport-restful-master",这暗示了项目使用了Git进行版本控制,"master"分支通常是主要的开发分支。 通过这个项目,我们可以学习到如何利用Flask和Flask-Restful构建RESTful ...
Thingworx获取Restful接口的方法;详细的代码使用案列,对初入Thingworx平台的朋友一定有帮助
以下是一些关于Laravel RESTful开发的重要知识点: 1. **路由**:Laravel的路由系统是实现RESTful API的关键。开发者可以使用`Route::get()`, `Route::post()`, `Route::put()`, `Route::delete()`等方法定义HTTP...
在开发RESTful接口时,我们需要遵循一定的设计规范来确保接口的一致性、可维护性和易用性。RESTful API(Representational State Transfer,也称为RESTful web服务)是一种提供互联网计算机系统间互操作性的方法。...
在C#环境中,开发RESTful API通常会利用ASP.NET Web API框架。本案例将详细介绍如何在C#中构建RESTful服务,并提供源代码以供参考。 一、RESTful原则简介 REST(Representational State Transfer,表现层状态转移)...
thinkphp6 RESTful API开发 开发过程记录笔记 https://blog.csdn.net/weixin_41120504/article/details/115638094
### RESTful Rails 开发知识点详解 #### 1.1 什么是 REST? REST(Representational State Transfer)是一种软件架构风格,最初由 Roy Fielding 在他的博士论文中提出。它定义了一组构建服务的原则和约束条件,...
使用工具进行RESTful开发** 在实际开发中,我们可以使用多种工具来辅助RESTful API的设计和测试,例如Postman、Swagger、curl等。这些工具可以帮助开发者构建和调试请求,查看响应,以及生成API文档。 综上所述,...
在RESTful架构中,服务端和客户端的交互是基于...理解HTTP方法、JAX-RS注解、媒体类型以及JSON处理是进行RESTful开发的基础。在实践中,还需要考虑错误处理、安全性、性能优化等因素,以构建高效、健壮的RESTful服务。
本文将深入探讨如何使用C和C++来实现HTTP服务,并开发RESTful API服务器。 首先,HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器。它是一个基于请求与...
这个C#的RESTful服务端和客户端Demo,旨在帮助开发者快速理解和实践RESTful API的设计和实现,是学习和开发相关应用的良好起点。通过实际操作和修改这个Demo,你可以更深入地了解RESTful架构的精髓以及C#在Web服务...