一、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>
跑一下