目前前后端分离编程已经成为各大公司的主流工作模式,这里面就涉及到了前后端的交互编程,而前后端的接口请求和参数传递就成了每天必须使用的技术,因此每个人都会接收前端传过来的参数。但是具体参数前端怎么传,后端怎么收,我相信很多人没有系统地研究过,今天我们就来通过代码来测测,参数传递到底有哪些姿势。
咱们的测试环境暂时使用jquery的ajax来实现参数的请求,后面会有单独的章节来讲解vue的请求。为了使用jquery,我们必须的引入jquery.js文件。我们可以从官网下载jquery.js文件,然后放入static目录下面。但今天我们通过使用webjars来引入jquery。具体步骤如下:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
推荐使用Webjars的三大理由:
所有 /webjars/** ,SpringBoot 都去 classpath:/META-INF/resources/webjars/ 找资源,位置如下:
想要浏览器访问引入的资源,路径: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";
}
}
然后运行,显示如下:
查看控制台输出,没有错误,说明jquery.js文件引入成功。
@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
后端代码:
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格式的参数。
上一节我们说了,通过@equestParam注解是无法接收json格式的参数的,因此这节我们介绍这个@RequestBody注解,它是专门来接收json格式注解的。
接收一个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();
}
$("#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的方式,来实现前后端的数据传输。
但是这种方式也有它的缺点,那就是对于必填函数和选填函数,在参数校验上需要单独进行处理。对于参数校验方式,这里就不在展开,后续我会单独写一篇教程,来进行详细的论述。
这个注解实现了从url的路径上获取传递过来的参数。这个注解对于搜索引擎来说是非常友好的,它会把动态的数据已静态的方式返回给搜索引擎,便于SEO的优化。
@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;
}
// 测试路径上的参数
$("#btnAddPath").bind('click', function() {
$.get(
"/addByPath/1/2",
function(result) {
console.log(result);
}
);
});
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>