口水篇
REST是设计风格而不是标准
资源是由URI来指定。
对资源的操作包括获取、创建、修改和删除资源
这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
通过操作资源的表现形式来操作资源。
常用操作
GET | 获取 |
POST | 提交 |
PUT | 更新 |
Delete | 删除 |
REST确实不是标准,只是设计风格,目的只是让url看起来更简洁实用,是资源状态的一种表达。
实战篇
Demo下载地址http://pan.baidu.com/s/1o6sJLZs
Maven依赖
|
<!-- Jar版本管理 -->
<
properties
>
<
springframework
>4.0.2.RELEASE</
springframework
>
<
log4j
>1.2.17</
log4j
>
<
jstl
>1.2</
jstl
>
</
properties
>
<
dependencies
>
<!-- Spring web mvc -->
<
dependency
>
<
groupId
>org.springframework</
groupId
>
<
artifactId
>spring-webmvc</
artifactId
>
<
version
>${springframework}</
version
>
</
dependency
>
<!-- JSTL -->
<
dependency
>
<
groupId
>jstl</
groupId
>
<
artifactId
>jstl</
artifactId
>
<
version
>${jstl}</
version
>
</
dependency
>
<!-- log4j -->
<
dependency
>
<
groupId
>log4j</
groupId
>
<
artifactId
>log4j</
artifactId
>
<
version
>${log4j}</
version
>
</
dependency
>
<!-- 单元测试 -->
<
dependency
>
<
groupId
>junit</
groupId
>
<
artifactId
>junit</
artifactId
>
<
version
>3.8.1</
version
>
<
scope
>test</
scope
>
</
dependency
>
</
dependencies
>
|
web.xml配置
需要注意,HiddenHttpMethodFilter是针对浏览器表单不支持put和delete方法而设计的,通过在表单中设置隐藏域,来分发到相应的处理器上,如<input type="hidden" name="_method" value="put" />
开发后记:最近把RESTful风格融入到了项目中去了,在开发过程中发现一个问题,就是aJax提交的PUT请求,无法通过HiddenHttpMethodFilter这个过滤器拿到值,后来搜索一番,改用HttpPutFormContentFilter
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!-- 通过http://java.sun.com/xml/ns/javaee/获取最新的schemaLocation -->
<
web-app
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xmlns:web
=
"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version
=
"3.0"
>
<
display-name
>SpringActivemqServer</
display-name
>
<!-- WebAppRootKey -->
<
context-param
>
<
param-name
>webAppRootKey</
param-name
>
<
param-value
>example.SpringActivemqServer</
param-value
>
</
context-param
>
<!-- Log4J Start -->
<
context-param
>
<
param-name
>log4jConfigLocation</
param-name
>
<
param-value
>classpath:log4j.properties</
param-value
>
</
context-param
>
<
context-param
>
<
param-name
>log4jRefreshInterval</
param-name
>
<
param-value
>6000</
param-value
>
</
context-param
>
<!-- Spring Log4J config -->
<
listener
>
<
listener-class
>org.springframework.web.util.Log4jConfigListener</
listener-class
>
</
listener
>
<!-- Log4J End -->
<!-- Spring 编码过滤器 start -->
<
filter
>
<
filter-name
>characterEncoding</
filter-name
>
<
filter-class
>org.springframework.web.filter.CharacterEncodingFilter</
filter-class
>
<
init-param
>
<
param-name
>encoding</
param-name
>
<
param-value
>UTF-8</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>forceEncoding</
param-name
>
<
param-value
>true</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>characterEncoding</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!-- Spring 编码过滤器 End -->
<!-- Spring Application Context Listener Start -->
<
context-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath*:applicationContext.xml</
param-value
>
</
context-param
>
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
</
listener
>
<!-- Spring Application Context Listener End -->
<!-- Spring MVC Config Start -->
<
servlet
>
<
servlet-name
>SpringMVC</
servlet-name
>
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet</
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath:spring-mvc.xml</
param-value
>
</
init-param
>
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>SpringMVC</
servlet-name
>
<!-- Filter all resources -->
<
url-pattern
>/</
url-pattern
>
</
servlet-mapping
>
<!-- Spring MVC Config End -->
<!-- 隐藏的HttpMethod方法过滤器,表单提交中需要携带一个name=_method的隐藏域,value=put或者delete -->
<
filter
>
<
filter-name
>HiddenHttpMethodFilter</
filter-name
>
<
filter-class
>org.springframework.web.filter.HiddenHttpMethodFilter</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>HiddenHttpMethodFilter</
filter-name
>
<
servlet-name
>SpringMVC</
servlet-name
>
</
filter-mapping
>
<
welcome-file-list
>
<
welcome-file
>index.jsp</
welcome-file
>
</
welcome-file-list
>
</
web-app
>
|
spring-mvc.xml配置
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ -->
<
beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:context
=
"http://www.springframework.org/schema/context"
xmlns:mvc
=
"http://www.springframework.org/schema/mvc"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 防止@ResponseBody中文乱码 -->
<
bean
class
=
"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
>
<
property
name
=
"messageConverters"
>
<
list
>
<
bean
class
=
"org.springframework.http.converter.StringHttpMessageConverter"
>
<
property
name
=
"supportedMediaTypes"
>
<
list
>
<
bean
class
=
"org.springframework.http.MediaType"
>
<
constructor-arg
index
=
"0"
value
=
"text"
/>
<
constructor-arg
index
=
"1"
value
=
"plain"
/>
<
constructor-arg
index
=
"2"
value
=
"UTF-8"
/>
</
bean
>
</
list
>
</
property
>
</
bean
>
</
list
>
</
property
>
</
bean
>
<!-- 启用MVC注解 -->
<
mvc:annotation-driven
/>
<!-- 静态资源文件,不会被Spring MVC拦截 -->
<
mvc:resources
location
=
"/resources/"
mapping
=
"/resources/**"
/>
<!-- 指定Sping组件扫描的基本包路径 -->
<
context:component-scan
base-package
=
"org.xdemo.example"
>
<!-- 这里只扫描Controller,不可重复加载Service -->
<
context:include-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
</
context:component-scan
>
<!-- JSP视图解析器-->
<
bean
class
=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<
property
name
=
"prefix"
value
=
"/WEB-INF/views/"
/>
<
property
name
=
"suffix"
value
=
".jsp"
/>
<
property
name
=
"order"
value
=
"1"
/>
</
bean
>
</
beans
>
|
applicationContext.xml
|
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!-- 查找最新的schemaLocation 访问 http:
//www.springframework.org/schema/ -->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans-4.0.xsd
http:
//www.springframework.org/schema/context
http:
//www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置扫描路径 -->
<context:component-scan base-
package
=
"org.xdemo.example"
>
<!-- 只扫描Service,也可以添加Repostory,但是要把Controller排除在外,Controller由spring-mvc.xml去加载 -->
<!-- <context:include-filter type=
"annotation"
expression=
"org.springframework.stereotype.Service"
/> -->
<!-- <context:include-filter type=
"annotation"
expression=
"org.springframework.stereotype.Repository"
/> -->
<!-- <context:include-filter type=
"annotation"
expression=
"org.springframework.stereotype.Component"
/> -->
<context:exclude-filter type=
"annotation"
expression=
"org.springframework.stereotype.Controller"
/>
</context:component-scan>
</beans>
|
User实体类
|
package
org.xdemo.example.springrestful.entity;
/**
* @作者 Goofy
* @邮件 252878950@qq.com
* @日期 2014-4-2下午1:40:32
* @描述 用户实体类
*/
public
class
User {
private
String userId;
private
String userName;
public
User(){}
public
User(String userId,String userName){
this
.userId=userId;
this
.userName=userName;
}
/**
* @return the userId
*/
public
String getUserId() {
return
userId;
}
/**
* @param userId the userId to set
*/
public
void
setUserId(String userId) {
this
.userId = userId;
}
/**
* @return the userName
*/
public
String getUserName() {
return
userName;
}
/**
* @param userName the userName to set
*/
public
void
setUserName(String userName) {
this
.userName = userName;
}
}
|
UserController
|
package
org.xdemo.example.springrestful.controller;
import
java.util.ArrayList;
import
java.util.List;
import
org.springframework.stereotype.Controller;
import
org.springframework.ui.ModelMap;
import
org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestMethod;
import
org.springframework.web.bind.annotation.ResponseBody;
import
org.springframework.web.servlet.ModelAndView;
import
org.xdemo.example.springrestful.entity.User;
/**
* @作者 Goofy
* @邮件 252878950@qq.com
* @日期 2014-4-2下午1:28:07
*/
@Controller
@RequestMapping
(
"/user"
)
public
class
UserController {
public
List<User> list=
null
;
/**
* user路径下默认显示用户列表
* @return
*/
@RequestMapping
(method=RequestMethod.GET)
public
ModelAndView index(){
if
(list==
null
){
list=getUserList();
}
ModelMap model=
new
ModelMap();
model.addAttribute(
"list"
,list);
return
new
ModelAndView(
"user/index"
,model);
}
/**
* 跳转到添加用户页面,约定优于配置,默认匹配文件/WEB-INF/views/user/add.jsp
*/
@RequestMapping
(
"add"
)
public
void
add(){}
/**
* 新增保存用户
* @param user
* @return ModelAndView
*/
@RequestMapping
(method=RequestMethod.POST)
public
ModelAndView addUser(User user){
if
(list==
null
){
list=getUserList();
}
list.add(user);
ModelMap model=
new
ModelMap();
model.addAttribute(
"list"
,list);
return
new
ModelAndView(
"user/index"
,model);
}
/**
* 查看用户详细信息
* @param id
* @return ModelAndView
*/
@RequestMapping
(method=RequestMethod.GET,value=
"{id}"
)
public
ModelAndView viewUser(
@PathVariable
(
"id"
)String id){
User user=findUserById(id);
ModelMap model=
new
ModelMap();
model.addAttribute(
"user"
,user);
return
new
ModelAndView(
"user/view"
,model);
}
/**
* 删除用户
* @param id
*/
@ResponseBody
@RequestMapping
(method=RequestMethod.DELETE,value=
"{id}"
)
public
String deleteUser(
@PathVariable
(
"id"
)String id){
if
(list==
null
){
list=getUserList();
}
removeUserByUserId(id);
return
"suc"
;
}
/**
* 跳转到编辑页面
* @param id
* @return ModelAndView
*/
@RequestMapping
(
"{id}/edit"
)
public
ModelAndView toEdit(
@PathVariable
(
"id"
)String id){
User user=findUserById(id);
ModelMap model=
new
ModelMap();
model.addAttribute(
"user"
,user);
return
new
ModelAndView(
"user/edit"
,model);
}
/**
* 更新用户并跳转到用户列表页面
* @param user
* @return ModelAndView
*/
@RequestMapping
(method=RequestMethod.PUT)
public
ModelAndView edit(User user){
updateUser(user);
return
new
ModelAndView(
"redirect:/user/"
);
}
/********************下面方法是操作数据的*********************/
/**
* 造10个用户
* @return List<User>
*/
private
List<User> getUserList(){
List<User> list=
new
ArrayList<User>();
for
(
int
i=
0
; i<
10
;i++){
list.add(
new
User((i+
1
)+
""
,
"李四"
+(i+
1
)));
}
return
list;
}
/**
* 删除用户
* @param id
* @return List<User>
*/
private
List<User> removeUserByUserId(String id){
if
(list==
null
)
return
null
;
for
(User user:list){
if
(user.getUserId().equals(id)){
list.remove(user);
break
;
}
}
return
list;
}
/**
* 查找用户
* @param id
* @return User
*/
private
User findUserById(String id){
User user=
null
;
if
(list==
null
)
return
null
;
for
(User _user:list){
if
(_user.getUserId().equals(id)){
user=_user;
break
;
}
}
return
user;
}
/**
* 更新用户
* @param user
*/
private
void
updateUser(User user){
for
(User _user:list){
if
(_user.getUserId().equals(user.getUserId())){
_user.setUserName(user.getUserName());
break
;
}
}
}
}
|
用户列表页面index.jsp
|
<%@ page language=
"java"
import
=
"java.util.*"
pageEncoding=
"UTF-8"
%>
<%@ taglib uri=
"http://java.sun.com/jsp/jstl/core"
prefix=
"c"
%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() +
"://"
+ request.getServerName() +
":"
+ request.getServerPort()
+ path +
"/"
;
%>
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
>
<html>
<head>
<base href=
"<%=basePath%>"
>
<title>用户列表</title>
<script type=
"text/javascript"
src=
"<%=basePath%>resources/jquery-1.11.0.min.js"
></script>
<style type=
"text/css"
>
a {
border: 1px solid rgb(
73
,
58
,
58
);
background-color: rgb(
133
,
133
,
133
);
height: 50px;
line-height: 50px;
color: white;
text-decoration: none;
font-weight: bold;
padding: 5px;
margin: 5px;
}
</style>
<script type=
"text/javascript"
>
function deleteUser(id){
$.ajax({
type:
'delete'
,
url:
'<%=basePath%>user/'
+id,
dataType:
'text'
,
success:function(data){
if
(data==
"suc"
){
alert(
"删除成功"
);
location.reload();
}
},
error:function(data){
}
});
}
</script>
</head>
<body>
<div style=
"margin:0 auto;width:500px;"
>
<a href=
"<%=basePath%>user/add"
>新增用户</a>
<table>
<tr>
<th>用户ID</th>
<th>用户名称</th>
<th>操作</th>
</tr>
<c:forEach var=
"user"
items=
"${list }"
>
<tr>
<td>${user.userId }</td>
<td>${user.userName }</td>
<td>
<a href=
"<%=basePath %>user/${user.userId}/edit"
>编辑用户</a>
<a href=
"<%=basePath %>user/${user.userId}"
>查看用户</a>
<a href=
"javascript:void(0);"
onclick=
"deleteUser(${user.userId })"
>删除该用户</a>
</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
|
编辑用户页面edit.jsp
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<
base
href="<%=basePath%>">
<
title
>新增用户页面</
title
>
</
head
>
<
body
>
<
div
style
=
"margin:0 auto;width:400px;"
>
<
form
action="<%=basePath%>user" method="post">
<!--此隐藏域可以被HiddenHttpMethodFilter所处理,然后分发到不同的HttpMethod的处理器上-->
<
input
type
=
"hidden"
name
=
"_method"
value
=
"put"
/>
<
table
>
<
tr
>
<
th
>用户ID</
th
>
<
th
>用户名称</
th
>
</
tr
>
<
tr
>
<
td
><
input
type
=
"text"
name
=
"userId"
id
=
"userId"
value
=
"${user.userId }"
readonly
=
"readonly"
/>
</
td
>
<
td
><
input
type
=
"text"
name
=
"userName"
id
=
"userName"
value
=
"${user.userName }"
/>
</
td
>
</
tr
>
<
tr
>
<
td
colspan
=
"2"
><
input
type
=
"submit"
value
=
"保存用户"
/>
</
td
>
</
tr
>
</
table
>
</
form
>
</
div
>
</
body
>
</
html
>
|
新增用户页面add.jsp
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<
base
href="<%=basePath%>">
<
title
>新增用户页面</
title
>
<
meta
http-equiv
=
"description"
content
=
"This is my page"
>
</
head
>
<
body
>
<
div
style
=
"margin:0 auto;width:400px;"
>
<
form
action="<%=basePath%>user" method="post">
<
table
>
<
tr
>
<
th
>用户ID</
th
>
<
th
>用户名称</
th
>
</
tr
>
<
tr
>
<
td
><
input
type
=
"text"
name
=
"userId"
id
=
"userId"
/>
</
td
>
<
td
><
input
type
=
"text"
name
=
"userName"
id
=
"userName"
/>
</
td
>
</
tr
>
<
tr
>
<
td
colspan
=
"2"
><
input
type
=
"submit"
value
=
"保存用户"
/>
</
td
>
</
tr
>
</
table
>
</
form
>
</
div
>
</
body
>
</
html
>
|
查看用户页面view.jsp
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<
base
href="<%=basePath%>">
<
title
>用户详情页面</
title
>
<
meta
http-equiv
=
"pragma"
content
=
"no-cache"
>
<
meta
http-equiv
=
"cache-control"
content
=
"no-cache"
>
<
meta
http-equiv
=
"expires"
content
=
"0"
>
<
meta
http-equiv
=
"keywords"
content
=
"keyword1,keyword2,keyword3"
>
<
meta
http-equiv
=
"description"
content
=
"This is my page"
>
</
head
>
<
body
>
<
div
style
=
"margin:0 auto;width:400px;"
>
<
form
action="<%=basePath%>user" method="post">
<
table
>
<
tr
>
<
th
>用户ID</
th
>
<
th
>用户名称</
th
>
</
tr
>
<
tr
>
<
td
>${user.userId}</
td
>
<
td
>${user.userName}</
td
>
</
tr
>
<
tr
>
<
td
colspan
=
"2"
><
input
type
=
"button"
value
=
"返回用户列表"
onclick
=
"history.go(-1)"
/>
</
td
>
</
tr
>
</
table
>
</
form
>
</
div
>
</
body
>
</
html
>
|