1)REST具體表現:
--- /account/1 HTTP GET 擷取id=1的account
--- /account/1 HTTP DELETE 删除id=1的account
--- /aacount/1 HTTP PUT 更新id=1的account
--- /account HTTP POST 新增account
2)SpringMVC中如何實作REST?
衆所周知,浏覽器form表單隻支援GET與POST請求,而DELETE、PUT等method并不支援。Spring3.0增加了一個過濾器,可以将這些請求轉化為标準的http方法,使得支援GET、POST、PUT及DELETE請求。
這個過濾器就是:org.springframework.web.filter.HiddenHttpMethodFilter
1 package org.springframework.web.filter;
2
3 import java.io.IOException;
4 import java.util.Locale;
5 import javax.servlet.FilterChain;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletRequestWrapper;
9 import javax.servlet.http.HttpServletResponse;
10
11 import org.springframework.util.Assert;
12 import org.springframework.util.StringUtils;
13 import org.springframework.web.util.WebUtils;
14
15 /**
16 * {@link javax.servlet.Filter} that converts posted method parameters into HTTP methods,
17 * retrievable via {@link HttpServletRequest#getMethod()}. Since browsers currently only
18 * support GET and POST, a common technique - used by the Prototype library, for instance -
19 * is to use a normal POST with an additional hidden form field ({@code _method})
20 * to pass the "real" HTTP method along. This filter reads that parameter and changes
21 * the {@link HttpServletRequestWrapper#getMethod()} return value accordingly.
22 *
23 * <p>The name of the request parameter defaults to {@code _method}, but can be
24 * adapted via the {@link #setMethodParam(String) methodParam} property.
25 *
26 * <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart
27 * POST request, due to its inherent need for checking a POST body parameter.</b>
28 * So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter}
29 * <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain.
30 *
31 * @author Arjen Poutsma
32 * @author Juergen Hoeller
33 * @since 3.0
34 */
35 public class HiddenHttpMethodFilter extends OncePerRequestFilter {
36
37 /** Default method parameter: {@code _method} */
38 public static final String DEFAULT_METHOD_PARAM = "_method";
39
40 private String methodParam = DEFAULT_METHOD_PARAM;
41
42
43 /**
44 * Set the parameter name to look for HTTP methods.
45 * @see #DEFAULT_METHOD_PARAM
46 */
47 public void setMethodParam(String methodParam) {
48 Assert.hasText(methodParam, "'methodParam' must not be empty");
49 this.methodParam = methodParam;
50 }
51
52 @Override
53 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
54 throws ServletException, IOException {
55
56 HttpServletRequest requestToUse = request;
57
58 if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
59 String paramValue = request.getParameter(this.methodParam);
60 if (StringUtils.hasLength(paramValue)) {
61 requestToUse = new HttpMethodRequestWrapper(request, paramValue);
62 }
63 }
64
65 filterChain.doFilter(requestToUse, response);
66 }
67
68
69 /**
70 * Simple {@link HttpServletRequest} wrapper that returns the supplied method for
71 * {@link HttpServletRequest#getMethod()}.
72 */
73 private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
74
75 private final String method;
76
77 public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
78 super(request);
79 this.method = method.toUpperCase(Locale.ENGLISH);
80 }
81
82 @Override
83 public String getMethod() {
84 return this.method;
85 }
86 }
87
88 }
從這個filter代碼中可以得知,該filter是通過POST方式送出表單,該表單中包含一個名稱為_method的隐藏域,該隐藏域的值用來判定将要轉化的請求方式。所謂的轉化請求方式,就是在該filter中重新生成了一個新的、标準化的請求。
3)如何使用到springmvc項目中?
步驟一:在web.xml中添加filter配置:
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
步驟二:在HelloWord.java中添加get/post/put/delete方法:
1 package com.dx.springlearn.handlers;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.web.bind.annotation.PathVariable;
5 import org.springframework.web.bind.annotation.RequestMapping;
6 import org.springframework.web.bind.annotation.RequestMethod;
7
8 @Controller
9 @RequestMapping("class_requestmapping")
10 public class HelloWord {
11 private static String SUCCESS = "success";
12
13 @RequestMapping(value = "/accountDelete/{id}", method = RequestMethod.DELETE)
14 public String accountDelete(@PathVariable("id") Integer id) {
15 System.out.println("test rest DELETE,account id:" + id);
16 return SUCCESS;
17 }
18
19 @RequestMapping(value = "/accountPut/{id}", method = RequestMethod.PUT)
20 public String accountPut(@PathVariable("id") Integer id) {
21 System.out.println("test rest PUT,account id:" + id);
22 return SUCCESS;
23 }
24
25 @RequestMapping(value = "/account", method = RequestMethod.POST)
26 public String account() {
27 System.out.println("test rest POST");
28 return SUCCESS;
29 }
30
31 @RequestMapping(value = "/account/{id}", method = RequestMethod.GET)
32 public String account(@PathVariable("id") Integer id) {
33 System.out.println("test rest GET,account id:" + id);
34 return SUCCESS;
35 }
36 }
步驟三:在index.jsp中添加get/post/put/delete方法請求的html腳本:
<!-- delete送出 -->
<form id="form_testRestMethod_DELETE" name="form_testRestMethod_DELETE" method="POST"
action="class_requestmapping/accountDelete/2">
<input type="hidden" name="_method" value="DELETE" />
<button name="submit" id="submit">test rest DELETE</button>
</form>
<br>
<!-- put送出 -->
<form id="form_testRestMethod_PUT" name="form_testRestMethod_PUT" method="POST"
action="class_requestmapping/accountPut/2">
<input type="hidden" name="_method" value="PUT" />
<button name="submit" id="submit">test rest PUT</button>
</form>
<br>
<!-- post送出 -->
<form id="form_testRestMethod_POST" name="form_testRestMethod_POST"
method="POST" action="class_requestmapping/account">
<button name="submit" id="submit">test rest POST</button>
</form>
<br>
<!-- get送出 -->
<a href="class_requestmapping/account/1">test rest GET</a>
<br>
步驟四:測試列印結果為: