REST(英文:Representational State Transfer,即表述性状态传递,简称REST)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。
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
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.apache.tomcatgroupId>
<artifactId>tomcat-apiartifactId>
<version>8.5.71version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.18version>
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后置的请求相悖,我们把拦截规则更换为:
/
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
新增
删除
修改
查询
默认情况下,HTML页面中的表单并不支持提交除GET/POST之外的请求,但SpringMVC提供有对应的过滤器来帮我们解决这个问题;
在web.xml中添加配置:
<filter>
<filter-name>methodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>methodFilterfilter-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;
}
}
}
修改后的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);
}
}