springMVC系列(七)——springMVC实现restful风格开发(post、get、put、delete)

Restful简介

Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

在Restful风格中,用户请求的url使用同一个url而用请求方式:get,post,delete,put...等方式对请求的处理方法进行区分,这样可以在前后台分离式的开发中使得前端开发人员不会对请求的资源地址产生混淆和大量的检查方法名的麻烦,形成一个统一的接口。

在Restful风格中,现有规定如下:

[plain]  view plain  copy
  1. GET(SELECT):从服务器查询,可以在服务器通过请求的参数区分查询的方式。  
  2. POST(CREATE):在服务器新建一个资源,调用insert操作。  
  3. PUT(UPDATE):在服务器更新资源,调用update操作。  
  4. DELETE(DELETE):从服务器删除资源,调用delete语句  
了解这个风格定义以后,我们举个例子:

如果当前url是 http://localhost:8080/User

那么用户只要请求这样同一个URL就可以实现不同的增删改查操作,例如

[plain]  view plain  copy
  1. http://localhost:8080/User?_method=get&id=1001  这样就可以通过get请求获取到数据库 user表里面 id=1001 的用户信息  
  2. http://localhost:8080/User?_method=post&id=1001&name=zhangsan  这样可以向数据库user 表里面插入一条记录  
  3. http://localhost:8080/User?_method=put&id=1001&name=lisi  这样可以将 user表里面 id=1001 的用户名改为lisi  
  4. 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方法,并打印返回数据。

[java]  view plain  copy
  1. /** 
  2.  * @author逝兮诚 
  3.  * @date 2017年5月17日下午3:53:53 
  4.  * get、post、put、delete的restful方式接口测试 
  5.  */  
  6. public classRestfulTest {  
  7.      
  8.     /** 
  9.      * get方式测试 
  10.      * @throws IOException 
  11.      */  
  12.     @Test  
  13.     public void testGet() throws IOException {  
  14.        Stringparam= "id=1&name=2";  
  15.        StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful" + "?"+ param;  
  16.        URLurl= newURL(urlStr);  
  17.        HttpURLConnectionconn= (HttpURLConnection)url.openConnection();  
  18.        conn.setRequestMethod("GET");  
  19.        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
  20.        InputStreamis = conn.getInputStream();  
  21.        int count = 0;  
  22.        while (count == 0) {  
  23.            count = is.available();  
  24.        }  
  25.        byte[] b = new byte[count];  
  26.        is.read(b);  
  27.        System.out.println(new String(b, "UTF-8"));  
  28.     }  
  29.      
  30.     /** 
  31.      * post方式测试 
  32.      * @throws IOException 
  33.      */  
  34.     @Test  
  35.     public void testPost() throws IOException {  
  36.        StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful";  
  37.        URLurl= newURL(urlStr);  
  38.        HttpURLConnectionconn= (HttpURLConnection)url.openConnection();  
  39.        conn.setRequestMethod("POST");  
  40.        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
  41.        conn.setDoOutput(true);  
  42.        conn.setDoInput(true);  
  43.        Stringparam= "id=1&name=2";  
  44.        conn.getOutputStream().write(param.getBytes());  
  45.        InputStreamis = conn.getInputStream();  
  46.        int count = 0;  
  47.        while (count == 0) {  
  48.            count = is.available();  
  49.        }  
  50.        byte[] b = new byte[count];  
  51.        is.read(b);  
  52.        System.out.println(new String(b, "UTF-8"));  
  53.     }  
  54.      
  55.     /** 
  56.      * put方式测试 
  57.      * @throws IOException 
  58.      */  
  59.     @Test  
  60.     public void testPut() throws IOException {  
  61.        StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful";  
  62.        URLurl= newURL(urlStr);  
  63.        HttpURLConnectionconn= (HttpURLConnection)url.openConnection();  
  64.        conn.setRequestMethod("PUT");  
  65.        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");  
  66.        conn.setDoOutput(true);  
  67.        conn.setDoInput(true);  
  68.        Stringparam= "id=1&name=2";  
  69.        conn.getOutputStream().write(param.getBytes());  
  70.        InputStreamis = conn.getInputStream();  
  71.        int count = 0;  
  72.        while (count == 0) {  
  73.            count = is.available();  
  74.        }  
  75.        byte[] b = new byte[count];  
  76.        is.read(b);  
  77.        System.out.println(new String(b, "UTF-8"));  
  78.     }  
  79.    
  80.     /** 
  81.      * del方式测试 
  82.      * @throws IOException 
  83.      */  
  84.     @Test  
  85.     public void testDel() throws IOException {  
  86.        StringurlStr= "http://127.0.0.1:8080/study_ssmvc/restful/1,2,3,4";  
  87.        URLurl= newURL(urlStr);  
  88.        HttpURLConnectionconn= (HttpURLConnection)url.openConnection();  
  89.        conn.setRequestMethod("DELETE");  
  90.        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
  91.        InputStreamis = conn.getInputStream();  
  92.        int count = 0;  
  93.        while (count == 0) {  
  94.            count = is.available();  
  95.        }  
  96.        byte[] b = new byte[count];  
  97.        is.read(b);  
  98.        System.out.println(new String(b, "UTF-8"));  
  99.     }  
  100. }  

实现接口

根据测试类,写好访问接口

[java]  view plain  copy
  1. @Controller  
  2. @RequestMapping("")  
  3. public classTestController {  
  4.          
  5.     /** 
  6.      * restful风格list接口 
  7.      * @param request 
  8.      * @param response 
  9.      * @param vo 
  10.      * @throws IOException 
  11.      */  
  12.     @RequestMapping(value = "/restful",method = RequestMethod.GET)  
  13.     public void list(HttpServletRequestrequest,HttpServletResponse response,TestVo vo) throws IOException {  
  14.        System.out.println("list被访问,参数:" + vo.toString());  
  15.        Map<String,Object> map= newHashMap<String, Object>();  
  16.        map.put("params",vo);  
  17.        map.put("method",RequestMethod.GET);  
  18.        response.getWriter().write(JSON.toJSONString(map));  
  19.     }  
  20.      
  21.     /** 
  22.      * restful风格update接口 
  23.      * @param request 
  24.      * @param response 
  25.      * @param vo 
  26.      * @throws IOException 
  27.      */  
  28.     @RequestMapping(value = "/restful",method = RequestMethod.POST)  
  29.     public voidupdate(HttpServletRequest request, HttpServletResponse response, TestVo vo) throws IOException {  
  30.        System.out.println("update被访问,参数:" + vo.toString());  
  31.        Map<String,Object> map= newHashMap<String, Object>();  
  32.        map.put("params",vo);  
  33.        map.put("method",RequestMethod.POST);  
  34.        response.getWriter().write(JSON.toJSONString(map));  
  35.     }  
  36.      
  37.     /** 
  38.      * restful风格add接口 
  39.      * @param request 
  40.      * @param response 
  41.      * @param vo 
  42.      * @throws IOException 
  43.      */  
  44.     @RequestMapping(value = "/restful",method = RequestMethod.PUT)  
  45.     public void add(HttpServletRequest request, HttpServletResponse response, TestVo vo) throws IOException {  
  46.         System.out.println("add被访问,参数:" + vo.toString());  
  47.        Map<String,Object> map= newHashMap<String, Object>();  
  48.        map.put("params",vo);  
  49.        map.put("method",RequestMethod.PUT);  
  50.        response.getWriter().write(JSON.toJSONString(map));  
  51.     }  
  52.      
  53.     /** 
  54.      * restful风格add接口 
  55.      * @param request 
  56.      * @param response 
  57.      * @param vo 
  58.      * @throws IOException 
  59.      */  
  60.     @RequestMapping(value = "/restful/{id}",method = RequestMethod.DELETE)  
  61.     public void del(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") String id) throws IOException {  
  62.         System.out.println("delete被访问,参数:"  + ", id:"+ id);  
  63.        Map<String,Object> map= newHashMap<String, Object>();  
  64.        map.put("params",id);  
  65.        map.put("method",RequestMethod.DELETE);  
  66.        response.getWriter().write(JSON.toJSONString(map));  
  67.     }  
  68. }  

配置及其他业务代码

这里要注意一下

1.html表单form中,method没有put、delete。

2.springMVC并不能直接接收到通过put、delete方式传过来的参数。

我这里的解决方式是

1.添加过滤器HttpPutFormContentFilter,作用是将put的参数获取并重新放入request中,controller便可以直接拿到这些参数,该过滤器支持put、patch,不支持delete。

配置代码        

[html]  view plain  copy
  1. <filter>  
  2.     <filter-name>httpPutFormFilter</filter-name>  
  3.     <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.     <filter-name>httpPutFormFilter</filter-name>  
  7.     <url-pattern>/*</url-pattern>  
  8. </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

[java]  view plain  copy
  1. public classTestVo {  
  2.      
  3.     private String id;  
  4.     private String name;  
  5.     public String getId() {  
  6.        return id;  
  7.     }  
  8.     public void setId(String id) {  
  9.        this.id = id;  
  10.     }  
  11.     public String getName() {  
  12.        return name;  
  13.     }  
  14.     public void setName(String name) {  
  15.        this.name = name;  
  16.     }  
  17.     public TestVo() {  
  18.        super();  
  19.     }  
  20.     @Override  
  21.     public String toString() {  
  22.        return "TestVo [id="+ id + ", name="+ name+ "]";  
  23.     }  
  24. }  

运行结果

运行测试类,测试全部通过


查看返回打印,确实是预期结果,测试通过

 

总结

这里要注意的是,delete并没有真正实现参数传输的问题,而是用url动态参数的方式实现。如果要实现delete的参数传输,我们可以使用HiddenHttpMethodFilter过滤器。它实际是将post请求转成delete、put请求使用。

其用法是在post传输参数中加一项”_method:xx”等于传输类型,”@RequestMapping(value = "/XXX", method =RequestMethod.DELETE)”方式去映射对应方法。

这种使用方式用法更加广泛、网上教程也更多,就不在累述了。


ajax中的post/get/delete/put请求方法的写法过于繁琐,所以现在封装成如下简便的形式:

 /**
     * 获取数据ajax-get请求
     * @author laixm
     */
    $.sanjiGetJSON = function (url,data,callback){
        $.ajax({
            url:url,
            type:"get",
            contentType:"application/json",
            dataType:"json",
            timeout:10000,
            data:data,
            success:function(data){
                callback(data);
            }
        });
    };

    /**
     * 提交json数据的post请求
     * @author laixm
     */
    $.postJSON = function(url,data,callback){
        $.ajax({
            url:url,
            type:"post",
            contentType:"application/json",
            dataType:"json",
            data:data,
            timeout:60000,
            success:function(msg){
                callback(msg);
            },
            error:function(xhr,textstatus,thrown){

            }
        });
    };

    /**
     * 修改数据的ajax-put请求
     * @author laixm
     */
    $.putJSON = function(url,data,callback){
        $.ajax({
            url:url,
            type:"put",
            contentType:"application/json",
            dataType:"json",
            data:data,
            timeout:20000,
            success:function(msg){
                callback(msg);
            },
            error:function(xhr,textstatus,thrown){

            }
        });
    };
    /**
     * 删除数据的ajax-delete请求
     * @author laixm
     */
    $.deleteJSON = function(url,data,callback){
        $.ajax({
            url:url,
            type:"delete",
            contentType:"application/json",
            dataType:"json",
            data:data,
            success:function(msg){
                callback(msg);
            },
            error:function(xhr,textstatus,thrown){

            }
        });
    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值