一、Restful
Restful 是什么?
REST即Representational State Transfer的缩写,可译为"表现层状态转化”。REST最大的几个特点为:资源、统一接口、URI和无状态。Restful是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和delete,即数据的增删查改)操作,分别对应于HTTP方法:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,这样就统一了数据操作的接口,仅通过HTTP方法,就可以完成对数据的所有增删查改工作。
即:
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
DELETE(DELETE):从服务器删除资源。
和传统风格做一下对比:
把上一个项目改造成Restful风格
1、listCategory.jsp
1、 在最开始增加了jquery.min.js的引入(得有jquery.min.js,并放在js这个目录下面)
<script type="text/javascript" src="js/jquery.min.js"></script>
2、增加
action修改为"categories"
3、删除
url修改为categories/id;
点击超链后,会使用form提交,并且提交_method的值为delete,以达到和增加类似的效果
<script type="text/javascript"> /*将post方法改为delete*/ $(function(){ $(".delete").click(function(){ var href=$(this).attr("href"); $("#formdelete").attr("action",href).submit(); return false; }) }) </script>
<a class="delete" href="categories/${c.id}">删除</a>
4、 获取
url修改为了/categories/id
listCategory.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> /*将post方法改为delete*/ $(function(){ $(".delete").click(function(){ var href=$(this).attr("href"); $("#formdelete").attr("action",href).submit(); return false; }) }) </script> <title>查看分类</title> </head> <body> <div style="width: 500px; margin: 20px auto; text-align: center"> <table align='center' border='1' cellspacing='0'> <tr> <td>id</td> <td>name</td> <td>编辑</td> <td>删除</td> </tr> <c:forEach items="${page.content}" var="c" varStatus="st"> <tr> <td>${c.id}</td> <td>${c.name}</td> <td><a href="categories/${c.id}">编辑</a></td> <td><a class="delete" href="categories/${c.id}">删除</a></td> </tr> </c:forEach> </table> <br> <div> <a href="?start=0">[首 页]</a> <a href="?start=${page.number-1}">[上一页]</a> <a href="?start=${page.number+1}">[下一页]</a> <a href="?start=${page.totalPages-1}">[末 页]</a> </div> <br> <form action="categories" method="post"> name: <input name="name"> <br> <button type="submit">提交</button> </form> <form id="formdelete" action="" method="POST" > <input type="hidden" name="_method" value="DELETE"> </form> </body> </html>
2、editCategory.jsp
action修改为了 categories/id
注意:form 下增加 filed, 虽然这个form的method是post, 但是springmvc看到这个_method的值是put后,会把其修改为put.
<input type="hidden" name="_method" value="PUT">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>修改</title> </head> <body> <div style="margin: 0px auto; width: 500px"> <form action="../categories/${c.id}" method="post"> <input type="hidden" name="_method" value="PUT"> name: <input name="name" value="${c.name}"> <br> <input name="id" type="hidden" value="${c.id}"> <button type="submit">提交</button> </form> </div> </body> </html>
3、CategoryController
CRUD的RequestMapping都修改为了/categories,以前用的注解叫做@RequestMapper,现在分别叫做 GetMapper, PutMapper, PostMapper 和 DeleteMapper 用于表示接受对应的Method
package edu.hpu.springboot.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import edu.hpu.springboot.dao.CategoryDao; import edu.hpu.springboot.pojo.Category; @Controller public class CategoryController { @Autowired CategoryDao categoryDao; @PostMapping("/categories") public String addCategory(Category c) throws Exception{ categoryDao.save(c); return "redirect:/categories"; } @DeleteMapping("/categories/{id}") public String deleteCategory(Category c) throws Exception{ categoryDao.delete(c); return "redirect:/categories"; } @GetMapping("/categories/{id}") public String getCategory(@PathVariable("id") int id,Model m) throws Exception { Category c= categoryDao.getOne(id); m.addAttribute("c", c); return "editCategory"; } @PutMapping("/categories/{id}") public String updateCategory(Category c) throws Exception{ categoryDao.save(c); return "redirect:/categories"; } @GetMapping("/categories") public String listCategory(Model m,@RequestParam(value = "start", defaultValue = "0") int start,@RequestParam(value="size",defaultValue="5")int size) throws Exception{ start = start<0?0:start; Sort sort=new Sort(Sort.Direction.DESC, "id"); Pageable pageable=new PageRequest(start, size, sort); Page<Category> page=categoryDao.findAll(pageable); System.out.println(page.getNumber()); System.out.println(page.getNumberOfElements()); System.out.println(page.getSize()); System.out.println(page.getTotalElements()); System.out.println(page.getTotalPages()); m.addAttribute("page", page); return "listCategory"; } }
跑一下,结果还是和前面差不多。
二、json
1、Category
增加个注解:@JsonIgnoreProperties({ “handler”,“hibernateLazyInitializer” }),因为jsonplugin用的是java的内审机制,hibernate会给被管理的pojo加入一个hibernateLazyInitializer属性,jsonplugin会把hibernateLazyInitializer也拿出来操作,并读取里面一个不能被反射操作的属性会产生异常,所以忽略掉这个属性。
package edu.hpu.springboot.pojo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; //对应category_的实体类 @Entity //表示这是个实体类 @Table(name="category_") //表示对应的表 @JsonIgnoreProperties({ "handler","hibernateLazyInitializer" }) public class Category { @Id //表示主键 @GeneratedValue(strategy = GenerationType.IDENTITY) //表明自增长方式 @Column(name="id") //表示对应的字段 private int id; @Column private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Category [id=" + id + ", name=" + name + "]"; } }
2、JsonCategoryController
@RestController=@RequestBody+@Controller
如果使用 @RestController 注解 Controller,则 Controller 中的方法无法返回 jsp 页面,或者 html,配置的视图解析器 InternalResourceViewResolver 将不起作用,直接返回内容。
package edu.hpu.springboot.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import edu.hpu.springboot.dao.CategoryDao; import edu.hpu.springboot.pojo.Category; @RestController public class JsonCategoryController { @Autowired CategoryDao categoryDao; @GetMapping("/category") public List<Category> listCategory(@RequestParam(value="start",defaultValue="0") int start, @RequestParam(value = "size", defaultValue = "5") int size) throws Exception{ start = start<0?0:start; Sort sort = new Sort(Sort.Direction.DESC, "id"); Pageable pageable = new PageRequest(start, size, sort); Page<Category> page =categoryDao.findAll(pageable); return page.getContent(); } @GetMapping("/category/{id}") public Category getCategory(@PathVariable("id") int id) { Category c= categoryDao.getOne(id); System.out.println(c); return c; } @PutMapping("/category") public void addCategory(@RequestBody Category category) { System.out.println("springboot接受到浏览器以JSON格式提交的数据:"+category); categoryDao.save(category); } }
在webapp下新建三个html文件
3、submit.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用AJAX以JSON方式提交数据</title> <script type="text/javascript" src="js/jquery.min.js"></script> </head> <body> <div align="center"> <form > id:<input type="text" id="id" value="123"><br> 名称:<input type="text" id="name" name="category xxx"><br> <input type="button" value="提交" id="sender"> </form> </div> <div id="messageDiv"></div> <script > $('#sender').click(function(){ var id=document.getElementById('id').value; var name=document.getElementById('name').value; var category={"name":name,"id":id}; var jsonData = JSON.stringify(category); var page="category"; $.ajax({ type:"put", url: "category", data:jsonData, dataType:"json", contentType : "application/json;charset=UTF-8", success: function(result){ } }); alert("提交成功,请在springboot控制台查看服务端接收到的数据"); }); </script> </body> </html>
4、getOne.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>通过Ajax查找一个数据</title> <script type="text/javascript" src="js/jquery.min.js"></script> </head> <body> <form > <input type="button" id="sender" value="通过Ajax获得一个对象"> </form> <div id="messageDiv"></div> <script > $('#sender').click(function(){ var url="category/50"; $.get( url, function(data) { console.log(data); var json=data; var name =json.name; var id = json.id; $("#messageDiv").html("分类id:"+ id + "<br>分类名称:" +name ); }); }); </script> </body> </html>
5、getMany.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>通过Ajax获得多个分类对象</title> <script type="text/javascript" src="js/jquery.min.js"></script> </head> <body> <input type="button" value="通过AJAX获取多个分类对象" id="sender"> <div id="messageDiv"></div> <script> $('#sender').click(function(){ var url="category?start=0&size=100"; $.get( url, function(data) { var categorys = data; for(i in categorys){ var old = $("#messageDiv").html(); var category = categorys[i]; $("#messageDiv").html(old + "<br>"+category.id+" ----- "+category.name); } }); }); </script> </body> </html>
跑一下