restful的认识和用法
目录
一、restful的认识
1、基本概念
(1)rest指的是一组架构约束条件和原则。 如果一个架构符合rest的约束条件和原则,我们就称它为restful架构。rest的意思是资源的表述性状态转移
(2)先看rest是什么意思,英文representational state transfer 表述性状态转移。其实就是对 资源 的表述性状态转移。
什么是表述性:就是指客户端请求一个资源,服务器拿到的这个资源,就是表述
资源的地址 在web中就是url (统一资源标识符)
资源是rest系统的核心概念。 所有的设计都是以资源为中心
(3)restful架构与传统的rpc、soap等方式在理念上有很大的不同
(4)目的:实现客户端无需借助任何文档即能调用到所有的服务器资源。客户只可以通过服务端所返回各结果中所包含的信息来得到下一步操作所需要的信息,如到底是向哪个url发送请求等。
2、规范和约束
restful 架构的核心规范与约束:统一接口。
分为四个子约束:
(1)每个资源都拥有一个资源标识,每个资源的资源标识可以用来唯一地标明该资源
就是写在controller上的访问路径
(2)消息的自描述性
比如content-type可以为application/x-www-form-urlencoded(标准的编码格式)、application/json、text/plain、application/xml、text/html
(3)资源的自描述性。
就是所带的参数
(4)超媒体作为应用状态引擎
一个网站里面肯定还有很多其他链接,链接到新链接,且链接容易被标识。
3、使用标准的状态码
(1)get
安全且幂等
表示获取
200(ok) - 表示已在响应中发出
204(无内容) - 资源有空表示
301(moved permanently) - 资源的uri已被更新
303(see other) - 其他(如,负载均衡)
304(not modified)- 资源未更改(缓存)
400 (bad request)- 指代坏请求(如,参数错误)
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
500 (internal server error)- 通用错误响应
503 (service unavailable)- 服务端当前无法处理请求
(2)post
不安全且不幂等
创建子资源
部分更新资源
200(ok)- 如果现有资源已被更改
201(created)- 如果新资源被创建
202(accepted)- 已接受处理请求但尚未完成(异步处理)
301(moved permanently)- 资源的uri被更新
303(see other)- 其他(如,负载均衡)
400(bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (precondition failed)- 前置条件失败(如执行条件更新时的冲突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (service unavailable)- 服务当前无法处理请求
(3)put
不安全但幂等
通过替换的方式更新资源
200 (ok)- 如果已存在资源被更改
201 (created)- 如果新资源被创建
301(moved permanently)- 资源的uri已更改
303 (see other)- 其他(如,负载均衡)
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (precondition failed)- 前置条件失败(如执行条件更新时的冲突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (service unavailable)- 服务当前无法处理请求
(4)delete
不安全但幂等
删除资源
200 (ok)- 资源已被删除
301 (moved permanently)- 资源的uri已更改
303 (see other)- 其他,如负载均衡
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
409 (conflict)- 通用冲突
500 (internal server error)- 通用错误响应
503 (service unavailable)- 服务端当前无法处理请求
二、具体使用
1、简单概括
url | 请求方式 | 作用 |
---|---|---|
/emp/{id} | get | 查询一个员工 |
/emp | get | 查询所有员工 |
/emp | post | 保存一个员工 |
/emp/{id} | put | 修改一个员工 |
/emp/{id} | delete | 删除一个员工 |
2、根据id查询一个员工
------controller端-----
@requestmapping("/emp/{empid}") @responsebody public emp getempbyid(@pathvariable long empid) { emp emp= empservice.getempbyid(empid); return emp; } <!--emp就一个pojo-->
------serviceimpl端-----
@override public emp getempbyid(long empid) { emp emp = empmapper.selectbyprimarykey(empid); return emp; }
------前端的ajax-----
function getemp(empid){ $.ajax({ url : "${pro_path}/emp/"+empid, type : "get", //请求成功的回调函数 success : function(result) { $("#一个input的id").val(result.empname); } }); }
3、查询所有员工
------controller端-----
<!-- 分页查询的参数:page传入页码,rows以及每页的大小--> @requestmapping("/emp/list") @responsebody public pageinfo getemplist(integer page, integer rows) { return empservice.getemplist(page, rows); }
------serviceimpl端-----
public pageinfo getemplist(int page, int rows) { //设置分页信息 pagehelper.startpage(page, rows); //执行查询 empexample example = new empexample(); list<emp> list = empmapper.selectbyexample(example); //取查询结果 pageinfo<emp> pageinfo = new pageinfo<>(list); //返回结果 return pageinfo; }
------前端的ajax-----
function to_page(page) { $.ajax({ url : "${pro_path}/emp/list", data: '{"page": page, "rows": 8}', type : "get", //请求成功的回调函数 success : function(result) { //数据表单展示: $.each(result.list,function(index, item) { //将表格内容显示出来 var checkboxtd=$("<td><input type='checkbox'/></td>"); var empidtd = $("<td></td>").append(item.empid); var empnametd = $("<td></td>").append(item.empname); $("<tr></tr>").append(checkboxtd).append(empidtd).append(empnametd).appendto("#tbody的id"); }); 页面情况展示: $("#div的id").append("当前第" + result.pagenum + "页 共有" + result.pages+ "页 总计" + result.total + "条记录"); 页数导航: var ul = $("<ul></ul>"); $.each(result.navigatepagenums, function(index, item) { var eachpgaenumli = $("<li></li>").append( $("<a></a>").append(item)); //添加单击事件 eachpgaenumli.click(function() { to_page(item); }); ul.append(eachpgaenumli); }); var navele = $("<nav></nav>").append(ul); navele.appendto("#div的id"); } }); }
4、保存一个员工
------controller端-----
//保存员工(一般有用到jsr303校验) @requestmapping(value="/saveemp",method=requestmethod.post) @responsebody public dataresult saveemp(@valid employee employee,bindingresult result) { if(result.haserrors()) { map<string,object> map=new hashmap<string,object>(); //result校验失败,应该返回失败 ,在模态框中显示校验失败的错误信息 list<fielderror> errors=result.getfielderrors(); for (fielderror fielderror : errors) { map.put(fielderror.getfield(), fielderror.getdefaultmessage()); } dataresult.build( dataresult.error ,null, map); }else { return employeeservice.saveemp(employee); } } <!--dataresult是一个处理结果的pojo, 包含属性 : 响应业务状态 private integer status; 响应消息 private string msg; 响应中的数据 private object data; -->
------serviceimpl端-----
public dataresult saveemp(employee employee) { employeemapper.insertselective(employee); return dataresult.ok(); }
------前端的ajax-----
$.ajax({ url:"${pro_path}/saveemp", type:"post", data:$("#form的id").serialize(), success:function(result){ //保存成功后: if(result.status==100){ 。。。此处省略。。。 }else{ // 保存失败后 //如果有邮箱的错误信息 if(result.data.email!=undefined){ 。。。此处省略。。。 } //如果有用户名的错误 if(result.data.empname!=undefined){ 。。。此处省略。。。 } } } });
5、根据id修改员工
------controller端-----
/* * 根据id修改员工 * 注意传递的id名字要和employee 的属性名一样 */ @requestmapping(value="/updateemp/{empid}",method=requestmethod.put) @responsebody public dataresult updateemp(employee employee) { return employeeservice.updateemp(employee); }
------serviceimpl端-----
public dataresult updateemp(employee employee) { employeemapper.updatebyprimarykeyselective(employee); return dataresult.ok(); }
------前端的ajax-----
var id=$(this).attr("edit-id"); $.ajax({ url : "${pro_path}/updateemp/"+id, type : "post", data:$("#form的id").serialize()+"&_method=put", success : function(result) { } });
6、删除一个员工
------controller端-----
@requestmapping(value="/deleteempbyid/{id}",method=requestmethod.delete) @responsebody public dataresult deleteempbyid(@pathvariable("id")integer id) { return employeeservice.deleteempbyid(id); }
------serviceimpl端-----
public dataresult deleteempbyid(integer id) { employeemapper.deletebyprimarykey(id); return dataresult.ok(); }
------前端的ajax-----
$.ajax({ url : "${pro_path}/deleteempbyid/"+empid, type : "delete", success : function(result) { } });
7、批量删除多个员工
------controller端-----
@requestmapping(value="/deleteempsbyid/{ids}",method=requestmethod.delete) @responsebody public processmsg deleteempsbyid(@pathvariable("ids")string ids) { //如果是多个id if(ids.contains("-")) { string[] str_id=ids.split("-"); list<integer> list_id=new arraylist<integer>(); for(string item_id:str_id) { list_id.add(integer.parseint(item_id)); } return employeeservice.deletebatch(list_id); //如果是一个id }else { return employeeservice.deleteempbyid(integer.parseint(ids)); } }
------serviceimpl端-----
public dataresult deletebatch(list<integer> str_id) { employeeexample employeeexample=new employeeexample(); criteria criteria=employeeexample.createcriteria(); criteria.andempidin(str_id); employeemapper.deletebyexample(employeeexample); return dataresult.ok(); } public dataresult deleteempbyid(integer id) { employeemapper.deletebyprimarykey(id); return dataresult.ok(); }
------前端的ajax-----
$("#emp_delete_all_btn").click(function() { var del_id_str=""; $.each($(".check_item:checked"),function(){ del_id_str+=$(this).parents("tr").find("td:eq(1)").text()+"-"; }); //去除最后一个逗号,分号 del_id_str=del_id_str.substring(0 , del_id_str.length-1); $.ajax({ url : "${pro_path}/deleteempsbyid/"+del_id_str, type : "delete", success : function(result) { } }); });