[TOC]
RESTful 开发风格
- REST - 表现层状态转换,资源在网络中以某种表现形式进行状态转移
- RESTful是基于REST理念的一套开发风格,是具体的开发规则
RESTful 开发规范
- 使用URL作为用户交互入口
- 明确的语义规范(GET POST PUT DELETE)
- 只返回数据(JSON|XML) 不包含任何展现
基本的使用
/**
* @author prim
*/
@Controller
@RequestMapping("/restful")
public class RestfulController {
//------------------------------ 基本的使用 -----------------------------------------//
@GetMapping("/t")
@ResponseBody
public String test() {
return "{\"message\":\"This is Message 中文\"}";
}
@PostMapping("/t")
@ResponseBody
public String doPostRequest(){
return "{\"message\":\"This is Message POST请求 增加操作\"}";
}
@PutMapping("/t")
@ResponseBody
public String doPutRequest(){
return "{\"message\":\"This is Message PUT请求 更新操作\"}";
}
@DeleteMapping("/t")
@ResponseBody
public String doDeleteRequest(){
return "{\"message\":\"This is Message DELETE请求 删除操作\"}";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
$("#btn").click(function () {
$.ajax({
url: "/restful/t",
type: "get",
dataType: "json",
success: function (json) {
$("#result").text(json.message);
}
})
});
$("#btnPost").click(function () {
$.ajax({
url: "/restful2/t/100",
type: "post",
dataType: "json",
success: function (json) {
$("#result").text(json.message + ":" + json.id);
}
})
});
$("#btnPut").click(function () {
$.ajax({
url: "/restful/t",
type: "put",
dataType: "json",
success: function (json) {
$("#result").text(json.message);
}
})
});
$("#btnDelete").click(function () {
$.ajax({
url: "/restful/t",
type: "delete",
dataType: "json",
success: function (json) {
$("#result").text(json.message);
}
})
});
});
</script>
</head>
<body>
<h1>This is Test RESTful</h1>
<input id="btn" name="btn" type="button" value="发送GET请求">
<input id="btnPost" name="btn" type="button" value="发送Post请求">
<input id="btnPut" name="btn" type="button" value="发送Put请求">
<input id="btnDelete" name="btn" type="button" value="发送Delete请求">
<h2 id="result"></h2>
</body>
</html>
RestController注解与路径变量
/**
* @author prim
*/
@RestController //Restful风格的注解 不用在每个方法上写@ResponseBody了
@RequestMapping("/restful2")
public class RestfulController2 {
///restful2/t/{?} 放在uri中的变量成为路径变量 这样使用很普遍的
//POST /restful2/t/100 如何获取到100呢?
//通过@XXXMapping(/xx/{id}) 注入路径变量
//通过@PathVariable 注入给参数
@PostMapping("/t/{rid}")
public String doPostRequest(@PathVariable("rid") Integer requestId) {
return "{\"message\":\"This is Message POST请求 增加操作\",\"id\":" + requestId + "}";
}
}
简单请求和非简单请求
- 简单请求是指标准结构的http请求,对应GET/POST请求
- 非简单请求是复杂要求的HTTP请求,指PUT DELETE、扩展标准(如:自定义请求头等)请求
- 两者最大区别是非简单请求发送前需要发送预检请求
put和delete请求获取传递的参数,和get和post请求获取参数是不一样的.
$("#btnPut").click(function () {
$.ajax({
url: "/restful/t",
type: "put",
data: "name=lily&age=23",
dataType: "json",
success: function (json) {
$("#result").text(json.message);
}
})
});
@PutMapping("/t")
@ResponseBody
public String doPutRequest(Person person) {
System.out.println(person.getName() + ":" + person.getAge());
return "{\"message\":\"This is Message PUT请求 更新操作\"}";
}j
如果正常的传递参数,会无法获取到参数值,而会直接获取到 null:null
注意:必须要需要在web.xml中进行配置FormContentFilter 对于非简单请求的表单处理
<!-- 支持put和delete 非简单请求 表单处理 -->
<filter>
<filter-name>formContentFilter</filter-name>
<filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>formContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
JSON 序列化
<!-- jackson依赖 2.9之前的版本会有很严重的漏洞 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.3</version>
<type>bundle</type>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.3</version>
</dependency>
注意:要将新加入的jackson的jar包添加到WEB-INF/lib 中
然后不用其他配置就可以直接使用. 如下会自动返回JSON List的格式
@GetMapping("persons")
public List<Person> findPersons() {
List list = new ArrayList();
Person p1 = new Person();
p1.setName("lily");
p1.setAge(23);
p1.setBirthday(new Date());
list.add(p1);
Person p2 = new Person();
p2.setName("smith");
p2.setAge(22);
p2.setBirthday(new Date());
list.add(p1);
return list;
}
jackson 的坑,在时间处理上,不是很理想.需要如下对时间进行处理
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthday;
浏览器跨域访问
- 浏览器同源策略
同源策略阻止从一个域加载的脚本去获取另一个域上的资源. 只要协议、域名、端口有任何一个不同,都被当作是不同的域 浏览器Console看到Access-Control-Allow-Origin就代表域了
/**
* 交给jackson自动调整
*
* @param id
* @return
*/
@GetMapping("/person")
public Person findByPersonId(Integer id) {
Person person = new Person();
if (id == 1) {
person.setName("lily");
person.setAge(23);
} else {
person.setName("smith");
person.setAge(22);
}
return person;
}
@GetMapping("persons")
public List<Person> findPersons() {
List list = new ArrayList();
Person p1 = new Person();
p1.setName("lily");
p1.setAge(23);
p1.setBirthday(new Date());
list.add(p1);
Person p2 = new Person();
p2.setName("smith");
p2.setAge(22);
p2.setBirthday(new Date());
list.add(p1);
return list;
}
HTML 中允许跨域的标签,其他的标签都不允许跨域
- - 显示远程图片