Restful风格知识点
@RestController注解
在类上添加@RestController可以默认类中的所有方法都带有@ResponseBody注解,可以省去一个个添加的麻烦。
@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;
}
}
路径变量
@PathVariable注解可以让控制方法接收前端传来的请求中的路径变量。例如下面这个例子,无论前端传来1还是100这个id都能被控制方法中的requestId这个变量通过@PathVariable注解来接收从而在控制方法中使用。
// POST /restful/request/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 + "}";
}
简单请求与非简单请求
简单请求是指标准结构的HTTP请求对应GET/POST请求
非简单请求是复杂要求的HTTP请求指PUT/DELETE、扩展标准请求
两者最大区别是非简单请求发送前需要发送预检请求
SpringMVC默认只支持get、post请求,要处理非简单请求需要在web.xml中配置过滤器。
<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序列化
首先在项目中添加依赖。
<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>
然后在控制方法中返回实体对象即可,如果有多个实体需要返回,则可以使用List。
@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;
}
如果实体类中包含了日期变量,则需要使用特殊的注解进行格式转变。
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;
}
}
浏览器的跨域访问
同源策略:
同源策略阻止从一个域加载的脚本去获取另一个域上的资源
只要协议、域名、端口有任何一个不同,都被当作是不同的域
浏览器Console看到Access-Control-Allow-Origin就代表跨域了
例子:
允许跨域的标签:
<img>- 显示远程图片
<script>- 加载远程JS
<link> - 加载远程CSS
请求头中的Sec-Fetch-Mode:cors说明这是一个跨域访问的请求。
响应头中的Vary: Origin,Access-Control-Request-Method, Access-Control-Request-Headers通知浏览器这是一个允许跨域访问的url。
在控制类之前添加注解解决跨域访问问题。
使用@CrossOrigin注解添加允许访问的url。
maxAge参数设置缓存预检请求结果的时间。
@CrossOrigin(origins = {"http://localhost:8080","http://www.imooc.com"},maxAge = 3600)
在配置文件中添加配置解决跨域访问问题。
在applicationContext.xml中添加mvc:cors设置允许访问的url。
<mvc:cors>
<mvc:mapping path="/restful/**"
allowed-origins="http://localhost:8080,http://www.imooc.com"
max-age="3600"/>
</mvc:cors>
path代表允许访问哪个路径下的资源。
注:注解和配置一起使用时,以注解配置为准。