一、RESTful的概念和意义
1、什么是RESTful?
RESTful就是一个资源定位以及资源操作的风格。不是标准也不是协议,只是一种风格。基于这种风格设计的软件可以更加的简洁,更有层次。
- 资源:互联网所有的事物都可以被抽象为资源 url (只要互联网上的事物可以用一 个 url 来表示,那么它就是一个资源)
- 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应添加、删除、修改、查询。
2、为什么使用使用RESTful
互联网开始的网页是前端后端融在一起的,如 JSP 等。在桌面时代问题不大,但是近年来移动互联网的发展,各种类型的 Client 层出不穷,RESTful 可以通过一套统一的接口为 Web , iOS 和 Android 提供服务。客户端不需要绑定服务器相关的信息和服务层分离,一套服务系统可应用于多种客户端
3、url的RESTful实现
非 RESTful 的 http 的 url : http://localhost:8080/users/toUpdateUser.do?id=1&name=a&sex=aRESTful 的 url 是简洁的: http://localhost:8080/users - rest/1/2参数通过 url 传递, rest 接口返回 json 数据
4、传统方式操作资源
操作啥(原来 url )?操作谁(传入的参数)url 中先定义动作,然后传递的参数表明这个动作操作的是哪个对象(数据)先定位动作,然后定位对象http://localhost:8080/springmvc07/user/queryUserById.do?id=1 查询http://localhost:8080/springmvc07/user/saveUser.do 新增http://localhost:8080/springmvc07/user/updateUser.do 更新http://localhost:8080/springmvc07/user/deleteUserById.do?id=1 删除
二、使用RESTful风格
1、更改web.xml中Dispatcher的配置,将url-pattern更改为"/"
<servlet><servlet-name> springmvc_rest </servlet-name><servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class><init-param><param-name> contextConfigLocation </param-name><param-value> classpath:springmvc.xml </param-value></init-param></servlet><servlet-mapping><servlet-name> springmvc_rest </servlet-name><url-pattern> / </url-pattern></servlet-mapping>
2、在webapp目录下新建一个restful-test.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>restful风格</title> </head> <body> <h2>get:查询</h2> <a href="${pageContext.request.contextPath}/user-restful">restful的get请求方式</a><br> <a href="${pageContext.request.contextPath}/user-restful/1">restful的get请求方式,带参数 </a> <h2>post:添加</h2> <form action="${pageContext.request.contextPath}/user-restful/1/aa" method="post"> <input type="submit" value="提交"> </form> <h2>put:修改</h2> <form action="${pageContext.request.contextPath}/user-restful/1" method="post"> <!--提交方式必须是post--> <!--新增一个input:name="_method" value="put"--> <input type="hidden" name="_method" value="put"> <input type="submit" value="提交"> </form> <h2>delete:删除</h2> <form action="${pageContext.request.contextPath}/user-restful/1" method="post"> <!--提交方式必须是post--> <!--新增一个input:name="_method" value="delete"--> <input type="hidden" name="_method" value="delete"> <input type="submit" value="提交"> </form> </body> </html>
3、在controller文件夹下新建一个RestfulController.java
- @RequestMapping(value = "/{id}",method = RequestMethod.GET/POST/PUT/DELETE)等价于@GetMapping/PostMapping/PutMapping/DeleteMapping("/{id}")
- 这里的@PathVariable("")表示参数和前端页面的参数自动绑定
@RestController @RequestMapping("/user-restful") public class RestfulController { //查询所有:get //@RequestMapping(value = "/user",method = RequestMethod.GET) @GetMapping public void queryAll(){ System.out.println("RestfulController:查询....."); } //@RequestMapping(value = "/user/{id}",method = RequestMethod.GET) @GetMapping("/{id}") public void queryById(@PathVariable("id") int id){ System.out.println("RestfulController:查询带参数id为....."+id); } //添加:post //@RequestMapping(value = "/user/{id}", method = RequestMethod.POST) @PostMapping("/{id}/{name}") //要对应起来,才能输出 public void addUsers(@PathVariable("id") int id,@PathVariable("name") String name){ System.out.println("RestfulController:增加带参数id为....."+id); } //修改:put //@RequestMapping(value = "/user/{id}",method = RequestMethod.PUT) @PutMapping("/{id}") public void updateUsers(@PathVariable("id") Integer id){ System.out.println("RestfulController:修改带参数id为....."+id); } //删:delete //@RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE) @DeleteMapping("/{id}") public void delete(@PathVariable("id") Integer id){ System.out.println("RestfulController:删除带参数id为....."+id); } }
4、当点击删除和修改按钮时,输出语句失败?
注意,web程序中只支持GET和POST提交方式,需要PUT和DELETE提交,需要在web.xml中配置
<!-- 处理 PUT DELETE 提交方式需要的过滤器 --><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 >
同时需要jsp传递一个参数:_method=PUT/DELETE
<input type="hidden" name="_method" value="put/delete"> 固定的不能改
5、释放静态资源
设置静态资源解析
,
解决
404
的错误
DispatcherServlet
拦截
/
开头的所有请求,对静态资源的访问就报
404
错
在
springmvc.xml
中设置静态资源的解析:
<!-- 静态资源解析 访问 /js/** 的 url 从项目下 /js/ 下解析 --><mvc:resources location = "/js/" mapping = "/js/**" /><mvc:resources location = "/img/" mapping = "/img/**" /><mvc:resources location = "/css/" mapping = "/css/**" /><!-- 如果访问报错,使用配置 web 容器默认的 Servlet 来处理静态资源,上面的<mvc:resources location="/js/" mapping="/js/**"/> 需要注释 --><!-- 静态资源加载 , 核心控制器拦截的是所有请求 , 需要对静态资源请求进行放行 , 通过配置放行资源实现下面这个配置是可以放行所有的普通资源调用让 springMVC 不处理静态资源 , 如 .css .js .html .MP3 等 --><mvc:default-servlet-handler/><!-- 配置静态文资源解析,自动使用 default 这个 Servlet 解析 --><mvc:default-servlet-handler default-servlet-name = "default" />
三、练习使用
1.RESTful风格的查询所有,提交方式为GET
1.1在restful-test.jsp中
<input type = "button" id = "btn1" value = " 查询所有 " />
1.2、 给按钮添加点击事件,提交ajax请求
使用ajax要使用jQuery,所以引入标签
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script> <script type="text/javascript"> $(function () { $("#btn1").click(function (){ $.ajax({ url:'${pageContext.request.contextPath}/u-restful', //发送请求的地址 method:'GET', //查询没有返回值,使用Get方法 // data:'', //此处没有返回值 dataType:'json', //以json字符串的方式返回数据 // contentType:'', success:function (rdata){ console.log(rdata); //打印数据 }, error:function (){ } }) }) })
1.3、新建一个UserControllerByRestful.java
@Controller @RequestMapping("u-restful") public class UserControllerByRestful { //调用service @Autowired private UsersService usersService; @GetMapping public @ResponseBody List<Users> queryAll(){ List<Users> all=usersService.findAll(); return all; } }
点击查询所有:在控制台输出
1.4、ResponseEntity
ResponseEntity
类,扩展了
HttpEntity
类,新增了
status
成员变量,这样,一个
ResponseEntity
基本可 以代表完整的http
的请求或响应了。这其实就是
ResponseEntity
类的作用。
使用
ResponseEntity
作为
controller
的返回值,我们可以方便地处理响应的
header
,状态码以及
body
。
而通常使用的
@ResponseBody
注解,只能处理
body
部分。这也是为什么通常在下载场景中会使用
ResponseEntity
,因为下载需要设置
header
里的
content-type
以及特殊的
status
(比如
200
)。
@Controller @RequestMapping("u-restful") public class UserControllerByRestful { //调用service @Autowired private UsersService usersService; @GetMapping public @ResponseBody ResponseEntity<List<Users>> queryAll(){ try { List<Users> all=usersService.findAll(); if (all==null){ return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);//没有查询到数据时 } System.out.println("查询所有:"+all); return ResponseEntity.ok(all);//正常返回数据回去 }catch (Exception e){ e.printStackTrace(); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);//500报错了 } }
2、RESTful风格的根据id查询,提交方式为GET
2.1、 jsp页面里新增按钮
<input type = "button" id = "btn2" value = " 根据 id 查询 " />
2.2、给按钮添加点击事件,提交ajax请求
//RESTful 格式根据 id 查询$ ( "#btn2" ). click ( function () {$ . ajax ({url : "${pageContext.request.contextPath}/u-restful/5" , // 参数通过 /5 传递type : "GET" , //GET 表示查询async : "true" ,dataType : "json" ,success : function ( rdata ) {console . debug ( rdata );}});});
2.3、UserControllerByRestful中新增根据id查询的方法
//根据id查询 @GetMapping("/{id}") public @ResponseBody ResponseEntity<Users> queryById(@PathVariable("id") int id){ try { Users users=usersService.queryById(id); if (users==null){ return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);//没有查询到数据时 } System.out.println("查询所有:"+users); return ResponseEntity.ok(users);//正常返回数据回去 }catch (Exception e){ e.printStackTrace(); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);//500报错了 }
增删改
<input type="button" id="btn3" value="添加用户" /> <input type="button" id="btn4" value="修改用户" /> <input type="button" id="btn5" value="删除用户" />
这里data中用的是 键值对的方式
如果使用json的话则,controller参数中可以使用@RequestBody来绑定data中参数
data:“uname: ' ' , upassword:' ' ”
contentType: application/json;charset=utf-8
//RESTful格式添加 $("#btn3").click(function() { $.ajax({ url : "${pageContext.request.contextPath}/u-restful", type : "POST", data:'uname=lbc&upassword=123',//通过键值对的方式 async : "true", dataType : "json", success : function(rdata) { console.log(rdata); }, error:function (){ console.log("出错了") } }); }); //RESTful格式修改 $("#btn4").click(function() { $.ajax({ url : "${pageContext.request.contextPath}/u-restful", type : "POST", async : "true", dataType : "json", data : "userid=55&uname=sgz&upassword=456&_method=PUT", success : function(rdata) { console.log(rdata); }, error:function (){ console.log("出错了") } }); }); //RESTful格式删除 $("#btn5").click(function() { $.ajax({ url : "${pageContext.request.contextPath}/u-restful", type : "POST", async : "true", dataType : "json", data : "uid=54&_method=DELETE", success : function(rdata) { console.log(rdata); }, error:function (){ console.log("出错了") } }); });
UserControllerByRestful中新增方法
//增加用户 @PostMapping public ResponseEntity<Void> addUsers(Users users){ try { usersService.addUsers(users); }catch (Exception e){ e.printStackTrace(); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);//没有查询到数据时 } return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);//无任何返回 } //修改用户 @PutMapping public ResponseEntity<Void> updateUsers(Users users){ try { usersService.updateUsers(users); }catch (Exception e){ e.printStackTrace(); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);//没有查询到数据时 } return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);//无任何返回 } //删除用户 @DeleteMapping public ResponseEntity<Void> delUsers(@RequestParam("uid") int uid){ try { usersService.delUsers(uid); }catch (Exception e){ e.printStackTrace(); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);//没有查询到数据时 } return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);//无任何返回 }