SpringMVC RESTful风格
RESTful风格简述
REST:Representational State Transfer(表述性状态转移),他不是一种创新技术,他指的是一组架构约束条件和原则,若一个架构符合REST的约束条件和原则架构,那么他就称为RESTful架构。
RESTful的核心内容
表述性状态转移,所谓的表述指的是资源
的表述,资源就是真实存在的资源(图片、文本、视频、音频等)可以被调用的资源,若要使得该资源被调用那么就需要有唯一标示即URI
。状态的转移指的是资源在客户端发生变迁,进入后续的状态,通俗来说就是用户改变资源后,服务器需要进行相应的变动操作。
RESTful架构特点
- 统一了客户端访问资源的接口,无论后台什么样的资源都是通过相同的接口进行访问
- url更加简洁,易于理解,便于拓展
- 有利于不同系统间的资源共享(依托于第一点的统一接口)
我们知道HTTP协议的有两种基本形式有:GET、POST。
RESTful具体来讲就是HTTP协议的四种形式表示四种基本操作,所对应的操作如下:
- GET:获取资源
- POST:新建资源
- PUT:修改资源(POST)
- DELETE:删除资源 (POST)
在我们之前的传递参数的时候是这样的http://localhost:8080/***?names=wiki
,那么使用RESTful开发风格后,就是http://localhost:8080/***/wiki method='GET'
。这就就不需要?=这样的格式了。具体使用如下。
SpringMVC下使用RESTful风格进行开发
处理PUT和DELETE请求
我们知道url可以默认处理POST和GET请求,要想处理PUT和DELETE请求,就需要在xml中添加filter来将POST请求转换为PUT和DELETE请求。
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在控制器中的编写如下,我们最终是在index页面进行展示,所以我们不论进行添加、修改还是删除都会重定向到/getAll
,这样getAll方法中需要返回ModelAndView在index页面进行显示。
我们的add方法进行的是一个POST类型的提交,而HTTP会处理这样的请求,所以正常编写,
<form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/add" method="post">
而我们的编辑操作进行的是PUT请求,需要将PUT请求转化为POST请求,这时候就需要在jsp页面进行处理,增加隐藏域一个隐式的input
,其中指定name为_method
,值为PUT
,这样就成功的将PUT转化为了POST。
<div class="form-group">
<div class="col-sm-offset-1 col-sm-3">
<input type="hidden" name="_method" value="PUT"/>
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
同理,在删除的时候需要添加同样的处理,只不过这时候不讲值设置为DELETE
<form action="${pageContext.request.contextPath}/delete/${course.id}" method="post">
<button class="btn btn-danger btn-sm delete_btn" type="submit">
<input type="hidden" name="_method" value="DELETE"/>
<span class="glyphicon glyphicon-trash">删除</span>
</button>
</form>
我们之前说过有一个相同的接口,这里相同的接口指的是什么呢?那我们可以看看以下的代码
<form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/add" method="post">
<form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/update" method="post">
<form action="${pageContext.request.contextPath}/delete/${course.id}" method="post">
通过观察我们可以发现相同的接口就是action="${pageContext.request.contextPath}/update"
,通过RESTful这样一个规范来统一了客户端访问资源的接口,从而实现不同系统的资源共享。
package com.yanyi.controller;
import com.yanyi.dao.CourseDAO;
import com.yanyi.entity.Course;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class CourseController {
@Autowired
private CourseDAO courseDAO;
//只有Post请求才可以进入这个方法
@PostMapping(value = "/add")
public String add(Course course){
System.out.println(course);
courseDAO.add(course);
return "redirect:/getAll";
}
@GetMapping(value = "/getAll")
public ModelAndView getAll(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index");
modelAndView.addObject("course",courseDAO.getAll());
return modelAndView;
}
@GetMapping(value = "/getById/{id}")
public ModelAndView getById(@PathVariable(value = "id")int id) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("edit");
modelAndView.addObject("course", courseDAO.getById(id));
return modelAndView;
}
@PutMapping(value = "/update")
public String update(Course course){
courseDAO.update(course);
return "redirect:/getAll";
}
@DeleteMapping(value = "/delete/{id}")
public String delete(@PathVariable(value = "id") int id){
courseDAO.deleteById(id);
return "redirect:/getAll";
}
}