第十七节 SpringBoot参数传递方式

亮子 2021-05-11 14:00:50 20443 0 0 0

目前前后端分离编程已经成为各大公司的主流工作模式,这里面就涉及到了前后端的交互编程,而前后端的接口请求和参数传递就成了每天必须使用的技术,因此每个人都会接收前端传过来的参数。但是具体参数前端怎么传,后端怎么收,我相信很多人没有系统地研究过,今天我们就来通过代码来测测,参数传递到底有哪些姿势。

1、引入webjars

咱们的测试环境暂时使用jquery的ajax来实现参数的请求,后面会有单独的章节来讲解vue的请求。为了使用jquery,我们必须的引入jquery.js文件。我们可以从官网下载jquery.js文件,然后放入static目录下面。但今天我们通过使用webjars来引入jquery。具体步骤如下:

1)、添加webjars依赖

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>

推荐使用Webjars的三大理由:

  • 将静态资源版本化,更利于升级和维护。
  • 剥离静态资源,提高编译速度和打包效率。
  • 实现资源共享,有利于统一前端开发。

2)、引入jquery

所有 /webjars/** ,SpringBoot 都去 classpath:/META-INF/resources/webjars/ 找资源,位置如下:

图片alt

想要浏览器访问引入的资源,路径:localhost:8080/webjars/jquery/3.3.1/jquery.js

在templates目录下创建模板文件index.html文件,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/webjars/jquery/3.3.1/jquery.js"></script>

</head>
<body>
<h1>hello,world.</h1>
</body>
</html>

编写controller如下:

package com.shenmazong.demorequestparam.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
@Slf4j
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }
}

然后运行,显示如下:

图片alt

查看控制台输出,没有错误,说明jquery.js文件引入成功。

2、使用@RequestParam注解接收方式

(1)作用

@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)

(2)语法:
语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)

value:参数名

required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。

defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
(3)示例代码:

后端代码:

package com.shenmazong.demorequestparam.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@Slf4j
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @GetMapping(value = "/add")
    @ResponseBody
    public Object addByGet(@RequestParam("x") Integer x, @RequestParam("y") Integer y) {
        return (x+y);
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public Object addByPost(@RequestParam("x") Integer x, @RequestParam("y") Integer y) {
        return (x+y);
    }
}

前端代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/webjars/jquery/3.3.1/jquery.js"></script>

</head>
<body>
<h1>hello,world.</h1>
<input type="button" id="btnAddGet" value="测试GET">
<input type="button" id="btnAddPost" value="测试POST">
</body>
<script type="text/javascript" th:inline="javascript">
    $(function() {
        // get method
        // 语法:$(selector).get(url,data,success(response,status,xhr),dataType)
        $("#btnAddGet").bind('click', function() {
            $.get(
                "/add",
                { x: 1, y: 2 },
                function(result) {
                    console.log(result);
                }
            );
        });

        // post method
        // 语法:jQuery.post(url,data,success(data, textStatus, jqXHR),dataType)
        $("#btnAddPost").bind('click', function() {
            $.post(
                "/add",
                { x: 1, y: 2 },
                function(result){
                    console.log(result);
                }
            );
        });
    });
</script>
</html>

使用RequestParam注解的好处是可以接收前端传来的各种方法、各种格式的参数,但是他无法接收json格式的参数。

3、使用@RequestBody注解接收方式

上一节我们说了,通过@equestParam注解是无法接收json格式的参数的,因此这节我们介绍这个@RequestBody注解,它是专门来接收json格式注解的。

1)、后端代码

接收一个json参数,后端事先要定义一个对象,我们可以实现上一节的两个整数相加的的功能。对象类如下:

package com.shenmazong.demorequestparam.pojo;

import lombok.Data;

@Data
public class AddIntegers {
    private Integer x;
    private Integer y;
}

然后定义接口函数,代码如下:

    @PostMapping(value = "/addByJson")
    @ResponseBody
    public Object addByJson(@RequestBody AddIntegers addIntegers) {
        return addIntegers.getX()+addIntegers.getY();
    }
2)、前端代码
        $("#btnAddJson").bind('click', function() {
            $.ajax({
                contentType: 'application/json',
                type: 'POST',
                url: "/addByJson",
                dataType: "json",
                data: JSON.stringify({ x: 1, y: 2 }),
                success: function (message) {
                    console.log(message);
                },
                error: function (message) {
                    console.log(message);
                }
            });
        });

上述代码实现了和上一节一样的功能。@RequestBody是把前端传过来的json字符串反序列化成了一个对象,因此通过@RequestBody可以简化参数。目前互联网一线公司基本都是采用POST+JSON的方式,来实现前后端的数据传输。

但是这种方式也有它的缺点,那就是对于必填函数和选填函数,在参数校验上需要单独进行处理。对于参数校验方式,这里就不在展开,后续我会单独写一篇教程,来进行详细的论述。

4、使用@PathVariable注解接收方式

这个注解实现了从url的路径上获取传递过来的参数。这个注解对于搜索引擎来说是非常友好的,它会把动态的数据已静态的方式返回给搜索引擎,便于SEO的优化。

1)、后端代码
    @GetMapping(value = "/addByPath/{x}/{y}")
    @ResponseBody
    public Object addByPath(
            @PathVariable(name = "x", required = true) Integer x,
            @PathVariable(name = "y", required = true) Integer y) {
        return x+y;
    }
2)、前端代码
        // 测试路径上的参数
        $("#btnAddPath").bind('click', function() {
            $.get(
                "/addByPath/1/2",
                function(result) {
                    console.log(result);
                }
            );
        });

5、完整代码

1)、后端代码

package com.shenmazong.demorequestparam.controller;

import com.shenmazong.demorequestparam.pojo.AddIntegers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@Slf4j
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @GetMapping(value = "/add")
    @ResponseBody
    public Object addByGet(@RequestParam("x") Integer x, @RequestParam("y") Integer y) {
        return (x+y);
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public Object addByPost(@RequestParam("x") Integer x, @RequestParam("y") Integer y) {
        return (x+y);
    }

    @PostMapping(value = "/addByJson")
    @ResponseBody
    public Object addByJson(@RequestBody AddIntegers addIntegers) {
        return addIntegers.getX()+addIntegers.getY();
    }

    @GetMapping(value = "/addByPath/{x}/{y}")
    @ResponseBody
    public Object addByPath(
            @PathVariable(name = "x", required = true) Integer x,
            @PathVariable(name = "y", required = true) Integer y) {
        return x+y;
    }
}

前端完整代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/webjars/jquery/3.3.1/jquery.js"></script>

</head>
<body>
<h1>hello,world.</h1>
<input type="button" id="btnAddGet" value="测试GET">
<input type="button" id="btnAddPost" value="测试POST">
<input type="button" id="btnAddJson" value="测试JSON">
<input type="button" id="btnAddPath" value="测试PATH">
</body>
<script type="text/javascript" th:inline="javascript">
    $(function() {
        // get method
        // 语法:$(selector).get(url,data,success(response,status,xhr),dataType)
        $("#btnAddGet").bind('click', function() {
            $.get(
                "/add",
                { x: 1, y: 2 },
                function(result) {
                    console.log(result);
                }
            );
        });

        // post method
        // 语法:jQuery.post(url,data,success(data, textStatus, jqXHR),dataType)
        $("#btnAddPost").bind('click', function() {
            $.post(
                "/add",
                { x: 1, y: 2 },
                function(result){
                    console.log(result);
                }
            );
        });

        // 测试json格式参数
        $("#btnAddJson").bind('click', function() {
            $.ajax({
                contentType: 'application/json',
                type: 'POST',
                url: "/addByJson",
                dataType: "json",
                data: JSON.stringify({ x: 1, y: 2 }),
                success: function (message) {
                    console.log(message);
                },
                error: function (message) {
                    console.log(message);
                }
            });
        });

        // 测试路径上的参数
        $("#btnAddPath").bind('click', function() {
            $.get(
                "/addByPath/1/2",
                function(result) {
                    console.log(result);
                }
            );
        });
    });
</script>
</html>