RESTful Web Services之Struts2 REST
2016-03-30 22:57
405 查看
RESTful Web Services
REST即REpresentational State Transfer,REST 是一种基于网络的软件架构约束,使用HTTP协议进行数据交换。基于REST架构的Web Services叫做RESTful Web Services。REST的主要原则如下:
网络上的所有事物都可被抽象为资源(Resource)。 每个资源都有一个唯一的资源标识符(Resource Identifier)。 同一资源具有多种表现形式。 使用标准方法操作资源。 通过缓存来提高性能。 对资源的各种操作不会改变资源标识符。 所有的操作都是无状态的(Stateless)。
REST 架构是针对传统 Web 应用提出的一种改进,是一种新型的分布式软件设计架构。对于异构系统如何整合的问题,目前主流做法都集中在使用 SOAP、WSDL 和 WS-* 规范的 Web Services。而 REST 架构实际上也是解决异构系统整合问题的一种新思路。
现在的云服务提供支持REST的API,如OpenStack.
在这种原则下,网络上的各种资源可以有统一的命名规则,URI,人们可以通过URI来判断自己访问了什么资源,而不是只有开发人员能看懂某个方法,如user!list?page=1&pageSize=10
以下HTTP方法在RESTful Web Services里非常常用,至于具体的定义,还需看各个框架自己的设定,但大体一致。
Get方法, Provides a read only access to a resource
/UserService/users 查询user的list,read only
/UserService/users/1,查询id为1的user,read only
Put方法, Used to create a new resource
/UserService/users/2,增加一位user,id=2,idempotent幂等性
Delete, Used to remove a resource
/UserService/users/1,删除id为1的user,idempotent幂等性
Post, Used to update a existing resource or create a new resource
/UserService/users/2,更新id为2的user
OPTIONS, Used to get the supported operations on a resource
/UserService/users, 列出web services支持定义的某个list,Read Only
Struts2 REST实例
Struts2在自己的学习和做项目过程中都用过,下面以框架为例,开发一个REST架构的页面。步骤一:建立Struts2项目,除了Struts2最基本的jar包,还需rest,convention,json-lib,xstream四个jar包
步骤二:配置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.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="false" /> <!-- 只想用REST 就配置这个--> <!-- <constant name="struts.mapper.class" value="rest" /> --> <!-- REST和非REST风格一起用, 就配置这个--> <!-- <constant name="struts.action.extension" value="xhtml,,xml,json,action"/> --> <!-- 以上可以不设,不论哪种,都要设定以下项目 --> <!-- XXXAction类后缀,可以是Controller,那么所有控制器后缀都设为Controller--> <constant name="struts.convention.action.suffix" value="Action" /> <constant name="struts.convention.action.mapAllMatches" value="true" /> <constant name="struts.convention.default.parent.package" value="rest-default" /> <!-- Action类所在包名 --> <constant name="struts.convention.package.locators" value="action" /> </struts>
步骤三:编写User.java,UserDao.java,UserService.java,注意struts2 rest插件提供的默认REST方法
User.java
package com.rest.bean; public class User { private Integer id; private String userName; private Integer age; public User() { } public User(Integer id, String userName, Integer age) { super(); this.id = id; this.userName = userName; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
UserDao.java
package com.rest.dao; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.rest.bean.User; public class UserDao { private static Map<Integer,User> list = new HashMap<Integer,User>(); private Integer id = 6; // 以内存中的数据,模拟数据库的持久存储 static { list.put(1,new User(1,"Tom",22)); list.put(2,new User(2,"Josh",23)); list.put(3,new User(3,"Luisa",18)); list.put(4,new User(4,"John",26)); list.put(5,new User(5,"Kate",21)); } //增加或更新 public void insert(User user) { if(user.getId()==null) { user.setId(id++); } list.put(user.getId(),user); } //删除 public void deleteById(Integer id) { list.remove(id); } //查单个 public User selectById(Integer id) { return list.get(id); } //查全部 public List<User> selectUsers() { return new ArrayList<User>(list.values()); } }
UserService.java
package com.rest.service; import java.util.List; import com.rest.bean.User; import com.rest.dao.UserDao; public class UserService { private UserDao userDao = new UserDao(); public void insert(User user) { userDao.insert(user); } public void deleteById(Integer id) { userDao.deleteById(id); } public User selectById(Integer id) { return userDao.selectById(id); } public List<User> selectUsers(){ return userDao.selectUsers(); } }
以下是UserAction.java
对于增加操作,固定方法为editNew,返回的jsp页面名字自己定,我的例子返回”add”,那么Struts2会映射到content的user-add.jsp。而在提交表单时的方法则是create()
对于删除操作,固定方法为destory()
对于修改操作,跳转页面是带参数的edit()方法,提交表单时update()
对于查询操作,查全部是index(),查单个是show()
package com.rest.action; import java.util.Collection; 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.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.rest.bean.User; import com.rest.service.UserService; @Results( value = { @Result(name="success", type="redirectAction", params = {"actionName" , "user"}) }) public class UserAction extends ActionSupport implements ModelDriven<Object>{ private static final long serialVersionUID = 1L; private UserService userService = new UserService(); //id请求参数 private Integer id; private User model = new User(); private Collection<User> list; @Override public Object getModel() { return list != null ? list : model; } //从jsp获取id请求参数,并初始化成对应的User public void setId(Integer id) { if (id != null) { this.model = userService.selectById(id); } this.id = id; } /** * @TODO 处理不带 id 参数的 GET 查询请求,跳页面 * @return 进入 添加用户页面 /user/new */ public String editNew() { model = new User(); return "add"; } /** * @TODO 处理不带 id 参数的 POST 请求 * @TODO 增加用户,表单提交的action /user */ public HttpHeaders create() { // 保存用户 userService.insert(model); addActionMessage("添加用户成功"); return new DefaultHttpHeaders("success").disableCaching(); } /** * @TODO 处理带 id 参数的 DELETE 请求,这个请求需要在jsp页面加点东西 * @return 删除用户成功页面, /user/1 */ public String destroy() { userService.deleteById(id); addActionMessage("删除用户成功"); return "success"; } /** * @TODO 处理带 id 参数的 GET 查询请求,负责跳页面 * @return 进入 编辑特定用户页面 /user/2/edit */ public String edit() { return "edit"; } /** * @TODO 处理带 id 参数的 PUT 请求, 这个请求需要在jsp页面加点东西 * @return 更新用户成功页面,提交表单action /user/1 */ public String update() { userService.insert(model); addActionMessage("用户更新成功"); return "success"; } /** * @TODO 处理不带 id 参数的 GET 查询请求 * @return 进入首页 /user, index是默认方法,不是execute了 */ public HttpHeaders index() { list = userService.selectUsers(); //映射到WEB-INF/content/user-index.jsp上,jsp名称是 控制器-方法名 return new DefaultHttpHeaders("index").disableCaching(); } /** * @TODO 处理带 id 参数的 GET 查询请求,查单个user * @return 进入 /user/2 */ public HttpHeaders show() { return new DefaultHttpHeaders("show").setLocationId(id); } }
步骤三:配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>restcase</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> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
以下是jsp页面开发
- user-index.jsp,对应index()方法,注意此处的delete方法
<body> <div> 信息:<s:actionmessage /> </div> <table> <tr> <th>编号</th> <th>名称</th> <th>年龄</th> <th>操作</th> </tr> <s:iterator value="model"> <tr> <td><s:property value="id"/></td> <td><s:property value="userName"/></td> <td><s:property value="age"/></td> <td> <a href="user/${id}">查看show()</a> <a href="user/${id}/edit">修改edit()</a> <a href="user/${id}?_method=DELETE">删除delete()</a> </td> </tr> </s:iterator> </table> <a href="user/new">添加用户editNew()</a> </body>
user-show.jsp,对应show()
<body> <table> <tr> <th>编号</th> <td><s:property value="id"/></td> </tr> <tr> <th>名称</th> <td><s:property value="userName"/></td> </tr> <tr> <th>年龄</th> <td><s:property value="age"/></td> </tr> </table> <a href="${pageContext.request.contextPath}/user">返回</a> </body>
user-edit.jsp 对应edit()
<body> <div>修改用户,id为<s:property value="id"/></div> <s:form action="%{#request.contextPath}/user/%{id}" method="post"> <!-- 注意此处加的隐藏域,表示是put请求 --> <s:hidden name="_method" value="put" /> <table> <tr> <th>编号</th> <s:textfield name="id" disabled="true"/> </tr> <tr> <th>名称</th> <s:textfield name="userName" /> </tr> <tr> <th>年龄</th> <s:textfield name="age" /> </tr> <tr> <s:submit/> </tr> </table> </s:form> <a href="${pageContext.request.contextPath}/user">返回列表</a> </body>
user-add.jsp 对应editNew()
<div>增加新用户</div> <s:form action="%{#request.contextPath}/user" method="post"> <table> <tr> <th>名称</th> <td><s:textfield name="userName"/></td> </tr> <tr> <th>年龄</th> <td><s:textfield name="age"/></td> </tr> <tr> <th><a href="${pageContext.request.contextPath}/user">返回列表</a></th> <td><s:submit value="提交"/></td> </tr> </table> </s:form> </body>
测试结果
小结
对于Struts2的rest,要注意细节配置,尤其是put和delete方法。**Struts2还能把以上的访问转变成xml或json,方便网络传输,
如访问rest/user.xml,那么需要加
xmlpull-1.1.3.1.jar包;
如果访问rest/user.json,加json依赖的包
**commons-beanutils-1.8.3.jar
commons-lang-2.5.jar
commons-collections-3.1.jar
ezmorph-1.0.6.jar
json-lib-2.3-jdk15.jar**
相关文章推荐
- Spring启动容器初始化Listener
- openssl和java关于rsa的交互
- JAVA数组排序
- JAVAEE 框架 2016-3-30
- 安卓开发之Kotlin和java双实现仿qq空间下拉图片拉伸
- 自学java之hibernate安装及配置
- Java Map集合 转化为List 并为List排序
- Struts2与Struts1的区别
- #java读书笔记#多线程2
- Struts2在eclipse运行的必须包
- java基础--java.util.Date类型小结
- Java并发编程:线程池的使用
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- ajax中Json对象的使用(利用struts框架或者单独使用)
- Struts1和Struts2的区别和对比:
- #java读书笔记#多线程1
- 《JAVA源码分析》:Thread
- Java的类属性和实例属性
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- Spring Schedule 任务调度实现