您的位置:首页 > 编程语言 > Java开发

SpringMVC构建REST风格的URI

2016-06-16 09:04 483 查看
简介:REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。REST定义了一套优雅的URI访问规则

GEThttp://xiaofen/users
访问所有用户的信息

GEThttp://xiaofen/users/100访问id为100的用户的信息
POSThttp://xiaofen/user添加一个新的用户
DELETE  http://xiaofen/user/200删除id为200的用户信息

PUThttp://xiaofen/user/300更新id为300的用户的信息

答疑:
1.什么是DELETE、PUT请求

在Servlet API中 delete 请求定义了一个标准的删除动作,put请求定义了一个更新原有数据的操作,由于Web浏览器只支持GET和POST请求,因此DELETE即PUT请求方式少为开发者使用。以下摘取自 javax.servlet.http.HttpServlet
中部分代码

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
doGet(req, resp);
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req, resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}


2.SpringMVC如何实现DELETE请求即PUT请求?
由于Web浏览器并不支持DELETE请求和PUT请求,SpringMVC中采用POST请求加标识符的方式来标识浏览器端发起的是一个DELETE请求或者PUT请求,该过程需要如下两个步骤

保证Web浏览器发起的是一个POST请求以及携带一个表单字段_method 该表单字段的额值为DELETE 或者 PUT,以下为发送一个DELETE请求
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="/Spring_Student/js/jquery-2.1.3.min.js"></script>
<script>
$(function(){
$(".delete").click(function(){
$("#delete_form").attr("action",$(this).attr("href")).submit();
alert();
return false;
});
});
</script>
</head>
<body>
<table>
<c:forEach items="${requestScope.list}" var="item">
<tr>
<td>${item.name}</td>
<td>${item.sex}</td>
<td>${item.likes}</td>
<td><a href="/T/user/${item.id}"  class="delete" >删除</a> <a href="/T/user/${item.id}" >编辑</a></td>
</tr>
</c:forEach>
</table>
<form id="delete_form" method="post">
<input type="hidden" name="_method" value="delete"/>
</form>
</body>
</html>

配置org.springframework.web.filter.HiddenHttpMethodFilter 过滤器对所有被DispatcherServlet 响应的请求进行预处理,该处理操作完成请求对象的重包装,定义为一个SpringMVC能够识别的标注请求GET、POST、DELETE、PUT等
<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">
<!-- SpingMVC的前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置SpringMVC的IOC容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置拦截所有的请求 -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>dispatcher</serv
4000
let-name>
</filter-mapping>
</web-app>

HiddenHttpMethodFilter部分代码如下。
/*HttpServletRequestWrapper的包装类,重写了getMethod方法*/
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
}
/*该方法由service方法间接调度*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String paramValue = request.getParameter(this.methodParam);
if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}


3.如何访问REST URI中绑定的信息字段
以DELETE
 http://xiaofen/user/200删除id为200的用户信息
为例,该URI中携带了当前操作需要的唯一数据200,在控制器方法中如何定义一个DELETE请求以及如何获取该字段的值成为关键。
SpringMVC提供了@RequestMapping
注解来映射请求路径及定义请求方式等参数,value定义了URI,method定义了请求的方式。
@RequestMapping(value="/user/{id}",method=RequestMethod.DELETE)
public String delete(@PathVariable("id")Integer id){
userService.delete(id);
return "redirect:/users";
}
SpringMVC以URI中使用{id}的形式来标识一个信息字段同时提供了@PathVariable
注解将URI中标识的字段映射到方法的入参中,方便在程序中访问。
4.HttpPutFormContentFilter 和 HiddenHttpMethodFilter 的区别
都继承自OncePerRequestFilter,HiddenHttpMethodFilter
用来将特定的POST请求转为对应的DELETE或者PUT请求,HttpPutFormContentFilter用来保证PUT请求中的数据能够以ServletRequest.getParameter*() 方式获取,通常情况下不使用。

5.SpringMVC中文件上传需要使用POST请求
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring mvc rest