springMVC系列(七)——springMVC實現restful風格開發(post、get、put、delete)
- 2019 年 10 月 30 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/luo4105/article/details/72420622
Restful簡介
Restful風格的API是一種軟體架構風格,設計風格而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器交互類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。
在Restful風格中,用戶請求的url使用同一個url而用請求方式:get,post,delete,put...等方式對請求的處理方法進行區分,這樣可以在前後台分離式的開發中使得前端開發人員不會對請求的資源地址產生混淆和大量的檢查方法名的麻煩,形成一個統一的介面。
在Restful風格中,現有規定如下:
GET(SELECT):從伺服器查詢,可以在伺服器通過請求的參數區分查詢的方式。 POST(CREATE):在伺服器新建一個資源,調用insert操作。 PUT(UPDATE):在伺服器更新資源,調用update操作。 DELETE(DELETE):從伺服器刪除資源,調用delete語句
了解這個風格定義以後,我們舉個例子:
如果當前url是 http://localhost:8080/User
那麼用戶只要請求這樣同一個URL就可以實現不同的增刪改查操作,例如
http://localhost:8080/User?_method=get&id=1001 這樣就可以通過get請求獲取到資料庫 user表裡面 id=1001 的用戶資訊 http://localhost:8080/User?_method=post&id=1001&name=zhangsan 這樣可以向資料庫user 表裡面插入一條記錄 http://localhost:8080/User?_method=put&id=1001&name=lisi 這樣可以將 user表裡面 id=1001 的用戶名改為lisi http://localhost:8080/User?_method=delete&id=1001 這樣用於將資料庫user 表裡面的id=1001 的資訊刪除
這樣定義的規範我們就可以稱之為restful風格的API介面,我們可以通過同一個url來實現各種操作
實現
在springMVC中實現restful風格開發
測試
寫介面前,先寫好單元測試,這樣可以理清思路、效驗介面正確性,正所謂測試先行。
這裡,我通過訪問http://127.0.0.1:8080/study_ssmvc/restful介面的method不同來進入不同的controller方法,並列印返回數據。
/** * @author逝兮誠 * @date 2017年5月17日下午3:53:53 * get、post、put、delete的restful方式介面測試 */ public classRestfulTest { /** * get方式測試 * @throws IOException */ @Test public void testGet() throws IOException { Stringparam= "id=1&name=2"; StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful" + "?"+ param; URLurl= newURL(urlStr); HttpURLConnectionconn= (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); InputStreamis = conn.getInputStream(); int count = 0; while (count == 0) { count = is.available(); } byte[] b = new byte[count]; is.read(b); System.out.println(new String(b, "UTF-8")); } /** * post方式測試 * @throws IOException */ @Test public void testPost() throws IOException { StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful"; URLurl= newURL(urlStr); HttpURLConnectionconn= (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); conn.setDoOutput(true); conn.setDoInput(true); Stringparam= "id=1&name=2"; conn.getOutputStream().write(param.getBytes()); InputStreamis = conn.getInputStream(); int count = 0; while (count == 0) { count = is.available(); } byte[] b = new byte[count]; is.read(b); System.out.println(new String(b, "UTF-8")); } /** * put方式測試 * @throws IOException */ @Test public void testPut() throws IOException { StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful"; URLurl= newURL(urlStr); HttpURLConnectionconn= (HttpURLConnection)url.openConnection(); conn.setRequestMethod("PUT"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); conn.setDoOutput(true); conn.setDoInput(true); Stringparam= "id=1&name=2"; conn.getOutputStream().write(param.getBytes()); InputStreamis = conn.getInputStream(); int count = 0; while (count == 0) { count = is.available(); } byte[] b = new byte[count]; is.read(b); System.out.println(new String(b, "UTF-8")); } /** * del方式測試 * @throws IOException */ @Test public void testDel() throws IOException { StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful/1,2,3,4"; URLurl= newURL(urlStr); HttpURLConnectionconn= (HttpURLConnection)url.openConnection(); conn.setRequestMethod("DELETE"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); InputStreamis = conn.getInputStream(); int count = 0; while (count == 0) { count = is.available(); } byte[] b = new byte[count]; is.read(b); System.out.println(new String(b, "UTF-8")); } }實現介面
根據測試類,寫好訪問介面
@Controller @RequestMapping("") public classTestController { /** * restful風格list介面 * @param request * @param response * @param vo * @throws IOException */ @RequestMapping(value = "/restful",method = RequestMethod.GET) public void list(HttpServletRequestrequest,HttpServletResponse response,TestVo vo) throws IOException { System.out.println("list被訪問,參數:" + vo.toString()); Map<String,Object> map= newHashMap<String, Object>(); map.put("params",vo); map.put("method",RequestMethod.GET); response.getWriter().write(JSON.toJSONString(map)); } /** * restful風格update介面 * @param request * @param response * @param vo * @throws IOException */ @RequestMapping(value = "/restful",method = RequestMethod.POST) public voidupdate(HttpServletRequest request, HttpServletResponse response, TestVo vo) throws IOException { System.out.println("update被訪問,參數:" + vo.toString()); Map<String,Object> map= newHashMap<String, Object>(); map.put("params",vo); map.put("method",RequestMethod.POST); response.getWriter().write(JSON.toJSONString(map)); } /** * restful風格add介面 * @param request * @param response * @param vo * @throws IOException */ @RequestMapping(value = "/restful",method = RequestMethod.PUT) public void add(HttpServletRequest request, HttpServletResponse response, TestVo vo) throws IOException { System.out.println("add被訪問,參數:" + vo.toString()); Map<String,Object> map= newHashMap<String, Object>(); map.put("params",vo); map.put("method",RequestMethod.PUT); response.getWriter().write(JSON.toJSONString(map)); } /** * restful風格add介面 * @param request * @param response * @param vo * @throws IOException */ @RequestMapping(value = "/restful/{id}",method = RequestMethod.DELETE) public void del(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") String id) throws IOException { System.out.println("delete被訪問,參數:" + ", id:"+ id); Map<String,Object> map= newHashMap<String, Object>(); map.put("params",id); map.put("method",RequestMethod.DELETE); response.getWriter().write(JSON.toJSONString(map)); } }配置及其他業務程式碼
這裡要注意一下
1.html表單form中,method沒有put、delete。
2.springMVC並不能直接接收到通過put、delete方式傳過來的參數。
我這裡的解決方式是
1.添加過濾器HttpPutFormContentFilter,作用是將put的參數獲取並重新放入request中,controller便可以直接拿到這些參數,該過濾器支援put、patch,不支援delete。
配置程式碼
<filter> <filter-name>httpPutFormFilter</filter-name> <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class> </filter> <filter-mapping> <filter-name>httpPutFormFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
需要注意的是,只有context-type:application/x-www-form-urlencoded的請求才會被過濾。
2.對於delete,我採用url中的動態參數,即」…/restful/1,2,3,4」,鏈接最後一項1,2,3,4就是參數。springMVC通過」@PathVariable」獲得url動態參數。
參數包裝類TestVo
public classTestVo { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TestVo() { super(); } @Override public String toString() { return "TestVo [id="+ id + ", name="+ name+ "]"; } }運行結果
運行測試類,測試全部通過

查看返回列印,確實是預期結果,測試通過

總結
這裡要注意的是,delete並沒有真正實現參數傳輸的問題,而是用url動態參數的方式實現。如果要實現delete的參數傳輸,我們可以使用HiddenHttpMethodFilter過濾器。它實際是將post請求轉成delete、put請求使用。
其用法是在post傳輸參數中加一項」_method:xx」等於傳輸類型,」@RequestMapping(value = "/XXX", method =RequestMethod.DELETE)」方式去映射對應方法。
這種使用方式用法更加廣泛、網上教程也更多,就不在累述了。
項目地址:https://code.csdn.net/luo4105/study_ssmvc/tree/master
參考資料
1.http://www.cnblogs.com/qixiaoyizhan/p/5864233.html
