SpringMVC构建REST风格的URI

来源:互联网 发布:vcr制作软件 编辑:程序博客网 时间:2024/05/16 03:53

简介: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</servlet-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;}@Overridepublic String getMethod() {return this.method;}}/*该方法由service方法间接调度*/@Overrideprotected 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请求










0 0
原创粉丝点击