• 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
    
    • 1

    请求体:

    {"username":"zhangsan","age":20}
    
    • 1

    提交方式: post

    • 修改
    http://localhost:8080/user/1
    
    • 1
    • 请求体:
    {"username":"lisi","age":30}
    
    • 1

    提交方式:put

    • 删除
    http://localhost:8080/user/1
    
    • 1

    提交方式:delete

    • 查询
    http://localhost:8080/user/1
    
    • 1

    提交方式:get

    6.3 基于Rest风格的方法

    • 引入依赖:
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 实体类:
    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;    // 是否省会城市
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 测试代码:
    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    注意:restful风格的请求显然与我们之前的.form后置的请求相悖,我们把拦截规则更换为:/

    • 准备一个表单:
    • Demo01.jsp:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
    
    

    新增

    删除

    <%--建立一个名为_method的一个表单项--%>

    修改

    查询

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    6.4 配置HiddenHttpMethodFilter

    默认情况下,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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    相关源码:

    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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    1.Python 设计模式
    使用HTML+CSS技术制作篮球明星介绍网站
    LetCode 字符串匹配
    【软考】系统集成项目管理工程师(九)项目成本管理
    Linux发散小知识
    mysql的执行顺序和执行计划(一)
    gpt不能发送信息了?
    vue的双向数据绑定?动态给vue的data添加一个新的属性会发生什么?怎么解决?Object.defineProperty和proxy的对比?
    搭建Python虚拟环境
    最强大脑记忆曲线(13)--应用程序的加密及授权码的实现
  • 原文地址:https://blog.csdn.net/Bb15070047748/article/details/128105337