06【SpringMVC的Restful支持】


六、SpringMVC的Restful支持

REST(英文:Representational State Transfer,即表述性状态传递,简称REST)RESTful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

6.1 RESTFUL示例:

示例请求方式效果
/user/1GET获取id=1的User
/user/1DELETE删除id为1的user
/userPUT修改user
/userPOST添加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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

緑水長流*z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值