Restful开发风格
传统Web应用的问题
在传统模式下,客户端必定是支持html的浏览器,比如IE,Chorme等。目前互联网呈多元化的发展,处理浏览器,还有微信小程序,APP等应用客户端,这些客户端是不支持HTML的。我们希望这些客户端也可以通过HTML向后端进行通信,那该怎么办呢?这时,一种新的开发理念就产生了,那就是Restful开发。

REST与RESTful:
- Rest - 表现层状态转移
资源(比如图片/CSS文件)在网络中以某种表现形式(URL)进行状态转移
- RESTful是基于REST理念的一套开发风格,是具体的开发规则
只要符合RESTful开发规范,就可以认为是RESTful应用
RESTful传输数据:
RESTful开发规范:
- 使用URL作为用户交互入口
- 明确的语义规范(GET/POST/PUT/DELETE)
我们一般不怎么看到PUT/DELETE,这是因为在Web环境下,不支持PUT/DELETE请求
#GET:查询操作,POST:新增操作,PUT:更新操作,DELETE:删除操作
- 只返回数据(JSON|XML),不包含任何表现
Restful基本使用
RestController注解与路径变量
- RestController注解:简化开发(不用每个函数上写ResponseBody注解),表示返回数据而不是页面跳转
- 路径变量:获取路径中的变量值 ```java package com.imooc.restful.controller;
import com.imooc.restful.entity.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import java.util.Date; import java.util.List;
@RestController @RequestMapping(“/restful”) //@CrossOrigin(origins = {“http://localhost:8080","http://www.imooc.com"}) //@CrossOrigin(origins = “*”,maxAge = 3600) public class RestfulController { @GetMapping(“/request”) //@ResponseBody public String doGetRequest(){ return “{\”message\”:\”返回查询结果\”}”; }
// POST /article/1
// POST /restful/request/100
@PostMapping("/request/{rid}")
//@ResponseBody
public String doPostRequest(@PathVariable("rid") Integer requestId, Person person){
System.out.println(person.getName() + ":" + person.getAge());
return "{\"message\":\"数据新建成功\",\"id\":" + requestId + "}";
}
@PutMapping("/request")
//@ResponseBody
public String doPutRequest(Person person){
System.out.println(person.getName() + ":" + person.getAge());
return "{\"message\":\"数据更新成功\"}";
}
@DeleteMapping("/request")
//@ResponseBody
public String doDeleteRequest(){
return "{\"message\":\"数据删除成功\"}";
}
@GetMapping("/person")
public Person findByPersonId(Integer id){
Person p = new Person();
if(id==1){
p.setName("lily");
p.setAge(23);
}else if(id==2){
p.setName("smith");
p.setAge(22);
}
return p;
}
@GetMapping("/persons")
public List<Person> findPersons(){
List list = new ArrayList();
Person p1 = new Person();
p1.setName("lily");
p1.setAge(23);
p1.setBirthday(new Date());
Person p2 = new Person();
p2.setName("smith");
p2.setAge(22);
p2.setBirthday(new Date());
list.add(p1);
list.add(p2);
return list;
}
}
#@RestController注解相当于@ResponseBody + @Controller
<a name="YDfro"></a>
### 简单请求和非简单请求
- 简单请求是指标准结构的HTTP请求,对应GET/POST请求
- 非简单请求是复杂要求的HTTP请求,指PUT/DELETE,扩展标准请求
- 两者最大区别是非简单请求发送前需要发送**预检请求**
最早的Spring MVC,是为网页服务的,默认网页在表单提交的时候,只支持GET/POST请求,对于PUT/DELETE请求是不支持的。随着技术的演进,PUT/DELETE是SpringMVC必须要考虑的,但是有不能把PUT/DELETE的处理方式强塞进原有的代码中,所以SpringMVC做了一个折中的方案,即用“表单内容过滤器”对PUT/DELETE进行额外处理。
src/main/webapp/WEB-INF/web.xml
```java
<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序列化
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.imooc</groupId>
<artifactId>restful</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.9</version>
</dependency>
</dependencies>
</project>
RestfulController.java
#直接返回对象
@GetMapping("/person")
public Person findByPersonId(Integer id){
Person p = new Person();
if(id==1){
p.setName("lily");
p.setAge(23);
}else if(id==2){
p.setName("smith");
p.setAge(22);
}
return p;
}
entity/Person.java
#使用JsonFormat注解格式化时间
#本来的值是new Date(),不格式化显示时间戳,格式化之后会显示XXXX年XX月XX日 XX时:XX分:XX秒
package com.imooc.restful.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class Person {
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
RestfulController.java
@GetMapping("/persons")
public List<Person> findPersons(){
List list = new ArrayList();
Person p1 = new Person();
p1.setName("lily");
p1.setAge(23);
p1.setBirthday(new Date());
Person p2 = new Person();
p2.setName("smith");
p2.setAge(22);
p2.setBirthday(new Date());
list.add(p1);
list.add(p2);
return list;
}
跨域问题
- 同源策略阻止从一个域加载的脚本去获取另一个域上的资源
- 只要协议,域名,端口有任何一个不同,都被当做是不同的域
- 浏览器Console看到Access-Control-Allow-Origin就代表跨域了

HTML中允许跨域的标签: - 显示远程图片
