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