文章目录
- 六、SpringMVC的Restful支持
- 6.1 RESTFUL示例:
- 6.2 基于restful风格的url
- 6.3 基于Rest风格的方法
- 6.4 配置HiddenHttpMethodFilter
- 6.5 Restful相关注解
六、SpringMVC的Restful支持
REST(英文:Representational State Transfer,即表述性状态传递,简称REST)RESTful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
6.1 RESTFUL示例:
示例 | 请求方式 | 效果 |
---|---|---|
/user/1 | GET | 获取id=1的User |
/user/1 | DELETE | 删除id为1的user |
/user | PUT | 修改user |
/user | POST | 添加user |
请求方式共有其中,其中对应的就是HttpServlet中的七个方法:
Tips:目前我们的jsp、html,都只支持get、post。
6.2 基于restful风格的url
- 添加
URL:
http://localhost:8080/user
请求体:
{"username":"zhangsan","age":20}
提交方式: post
- 修改
http://localhost:8080/user/1
- 请求体:
{"username":"lisi","age":30}
提交方式:put
- 删除
http://localhost:8080/user/1
提交方式:delete
- 查询
http://localhost:8080/user/1
提交方式:get
6.3 基于Rest风格的方法
- 引入依赖:
<dependencies>
<!--包含Spring环境和SpringMVC环境-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>8.5.71</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
</dependencies>
- 实体类:
package com.dfbz.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author lscl
* @version 1.0
* @intro:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
private Integer id; // 城市id
private String cityName; // 城市名称
private Double GDP; // 城市GDP,单位亿元
private Boolean capital; // 是否省会城市
}
- 测试代码:
package com.dfbz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author lscl
* @version 1.0
* @intro:
*/
@Controller
@RequestMapping("/city")
public class CityController {
/**
* 新增
*/
@PostMapping
public void save(HttpServletResponse response) throws IOException {
response.getWriter().write("save...");
}
/**
* 删除
*
* @param id
* @param response
* @throws IOException
*/
@DeleteMapping("/{id}")
public void delete(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("delete...id: " + id);
}
/**
* 修改
*
* @param id
* @param response
* @throws IOException
*/
@PutMapping("/{id}")
public void update(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("update...id: " + id);
}
/**
* 根据id查询
*
* @param id
* @param response
* @throws IOException
*/
@GetMapping("/{id}")
public void findById(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("findById...id: " + id);
}
}
注意:restful风格的请求显然与我们之前的.form后置的请求相悖,我们把拦截规则更换为:
/
- 准备一个表单:
- Demo01.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>新增</h3>
<form action="/city" method="post">
<input type="submit">
</form>
<h3>删除</h3>
<form action="/city/1" method="post">
<%--建立一个名为_method的一个表单项--%>
<input type="hidden" name="_method" value="delete">
<input type="submit">
</form>
<h3>修改</h3>
<form action="/city/1" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit">
</form>
<h3>查询</h3>
<form action="/city/1" method="get">
<input type="submit">
</form>
</body>
</html>
6.4 配置HiddenHttpMethodFilter
默认情况下,HTML页面中的表单并不支持提交除GET/POST之外的请求,但SpringMVC提供有对应的过滤器来帮我们解决这个问题;
在web.xml中添加配置:
<filter>
<filter-name>methodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>methodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
相关源码:
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
private static final List<String> ALLOWED_METHODS;
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = "_method";
public HiddenHttpMethodFilter() {
}
public void setMethodParam(String methodParam) {
Assert.hasText(methodParam, "'methodParam' must not be empty");
this.methodParam = methodParam;
}
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
// 获取request中_method表单项的值
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
// 全部转换为大写(delete--->DELETE)
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter((ServletRequest)requestToUse, response);
}
static {
ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
}
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
// 修改request自身的的method值
super(request);
this.method = method;
}
public String getMethod() {
return this.method;
}
}
}
6.5 Restful相关注解
- @GetMapping:接收get请求
- @PostMapping:接收post请求
- @DeleteMapping:接收delete请求
- @PutMapping:接收put请求
修改后的CityController:
package com.dfbz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
@RequestMapping("/city")
public class CityController_RestFul {
/**
* 新增
*/
@PostMapping
public void save(HttpServletResponse response) throws IOException {
response.getWriter().write("save...");
}
/**
* 删除
*
* @param id
* @param response
* @throws IOException
*/
@DeleteMapping("/{id}")
public void delete(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("delete...id: " + id);
}
/**
* 修改
* @param id
* @param response
* @throws IOException
*/
@PutMapping("/{id}")
public void update(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("update...id: " + id);
}
/**
* 根据id查询
*
* @param id
* @param response
* @throws IOException
*/
@GetMapping("/{id}")
public void findById(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("findById...id: " + id);
}
}