Spring MVC中Controller接收请求参数的常见方式
在Spring中 Controller注解用于指示Spring类的实例是一个控制器,相对于实现Controller接口变得更加简单。而且实现Controller接口只能处理一个单一的请求,而是用@Controller注解可以支持同时处理多个请求动作,更加灵活。
@Controller用于标记一个类,使用他标记的类就是一个SpringMVC Controller对象,即一个控制器类,Spring使用扫描机制查找应用程序中所有基于注解的控制器类。分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解的方法才是真正处理请求的处理器。
非JSON方式接收请求参数
普通方式-请求参数名和Controller方法的参数一致
GET请求和POST请求都支持
@Controller
@RequestMapping("/param")
public class TestParamController {
private static final Logger logger = LoggerFactory.getLogger(TestParamController.class);
/**
* 请求参数名和Controller方法的参数一致
* produces 设置返回参数的编码格式可以设置返回数据的类型以及编码,可以是json或者xml
* {
* @RequestMapping(value="/xxx",produces = {"application/json;charset=UTF-8"})
* 或
* @RequestMapping(value="/xxx",produces = {"application/xml;charset=UTF-8"})
* 或
* @RequestMapping(value="/xxx",produces = "{text/html;charset=utf-8}")
* }
* @param name 用户名
* @param pwd 密码
* @return
*
*/
@RequestMapping(value = "/add", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
@ResponseBody
public String addUser(String name, String pwd) {
logger.debug("name:" + name + ",pwd:" + pwd);
return "name:" + name + ",pwd:" + pwd;
}
}
通过访问:GET http://localhost:8080/param/add?name=张三&pwd=123456
对象方式-请求参数名和Controller方法中的对象的参数一致
GET请求和POST请求都支持
Employee实体类:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
private Integer id;
private String lastName;
private Integer gender;
private String email;
private Integer dId;
}
controller实现
@RestController
@RequestMapping("/param")
@Slf4j
public class ParamsController {
@GetMapping("/employee")
public String addEmployee(Employee employee){
return "lastName:"+employee.getLastName()+",email:"+employee.getEmail();
}
}
通过访问:http://127.0.0.1:8080/param/employee?lastName=战三&email=33453432@qq.com
通过HttpServletRequst接收请求参数
GET请求和POST请求都支持
@RestController
@RequestMapping("/param")
public class TestParamController2 {
@RequestMapping(value = "/add2")
public String add(HttpServletRequest request){
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
return "name:" + name + ",pwd:" + pwd;
}
}
通过@RequestParam注解接收请求参数
GET请求和POST请求都支持
RequestParam注解作用:把请求中的指定名称的参数传递给控制器中的形参赋值
注解属性:
- value:请求参数中的名称
- required:请求参数中是否必须提供此参数,默认值是true,必须提供
- defaultValue:设置默认值,仅当传入参数为空时有效
@RestController
@RequestMapping("/param")
public class TestParamController3 {
@RequestMapping(value = "/add3")
public String add(@RequestParam(value = "name", required = false) String name, @RequestParam(value = "pwd", required = false) String pwd) {
return "name:" + name + ",pwd:" + pwd;
}
}
通过PathVariable注解接收请求参数
GET请求和POST请求都支持
PathVariable注解作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
注解属性 value:指定url中的占位符名称
优点:Restful风格的URL 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
@RestController
@RequestMapping("/param")
public class TestParamController4 {
@RequestMapping(path = "/hello/{id}")
public String sayHello(@PathVariable(value = "id") String id) {
return "id=" + id;
}
}
JSON格式接收请求入参
JSON格式接收普通对象
@RestController
@RequestMapping("/resp")
@Slf4j
public class ParamsRespController {
@PostMapping("/test")
public String addEmployee(@RequestBody Employee employee){
return "lastName:"+employee.getLastName()+",email:"+employee.getEmail();
}
}
JSON格式接收List对象
@RestController
@RequestMapping("/resplist")
@Slf4j
public class ParamsRespListController {
@PostMapping("/testlist")
public String addEmployee(@RequestBody List<Employee> employees){
StringBuilder sb = new StringBuilder("{");
if( null != employees){
for(Employee employee:employees){
sb.append("{"+"lastName:"+employee.getLastName()+",email:"+employee.getEmail()+"}");
}
}
sb.append("}");
return sb.toString();
}
}
JSON格式接收Map对象
@RestController
@RequestMapping("/respmap")
@Slf4j
public class ParamsRespMapController {
@PostMapping("/testmap")
public String addEmployee(@RequestBody Map<String,Employee> employees){
StringBuilder sb = new StringBuilder("[");
if( null != employees){
for(Map.Entry<String,Employee> employeeEntry : employees.entrySet()){
sb.append(employeeEntry.getKey()+":"+employeeEntry.getValue()+",");
}
}
sb.append("]");
return sb.toString();
}
}
Spring MVC接收数组的三种方式
第一种方式
页面正常通过Key-Value的形式传值,数组保持原格式,后端使用@RequestParam注解标注接值的入参,注意@RequestParam里的value一定要带上中括号:
@RequestMapping("/test.htm")
@ResponseBody
public AjaxResp test(@RequestParam("dataList[]") List<String> dataList, String name){
//do something
}
页面JS:
var dataList = [1,2,3];
$.get({
url: "/test.htm",
data: {dataList: dataList,name:'jack'},
success: function (data) {
//do something
}
});
这种方式的好处是简单,方便。get请求和post请求都可以传值,并且后台接值的参数类型可以是List集合也可以用String[]数组。不过这种方式可能报文看起来比较奇怪。
第二种方式
页面正常通过Key-Value的形式传值,数组使用逗号分割的形式的字符串(可以使用toString()或join()将数组转成这种格式),后端使用String[]数组接值。
@RequestMapping("/test.htm")
@ResponseBody
public AjaxResp test(String[] dataList, String name){
//do something
}
页面JS:
var dataList = "1,2,3";
$.get({
url: "/test.htm",
data: {dataList: dataList,name:'jack'},
success: function (data) {
//do something
}
});
注意这种方式后端接口得用String[]数组来接,如果你直接用List集合会抛下面这个异常:
Could not instantiate bean class [java.util.List]: Specified class is an interface
加上@RequestParam注解并且设置value之后就可以用List集合类型了:
@RequestMapping("/test.htm")
@ResponseBody
public AjaxResp test(@RequestParam("dataList") List<String> dataList, String name){
//do something
}
这种方式同样支持get和post请求,并且报文也没那么奇怪,推荐使用。
第三种方式
前台使用json来传值,后台使用一个数据对象来接值:
public class Dto {
private List<String> dataList;
private String name;
//getters and setters
}
controller,记得加上@RequestBody,spring才能帮我们解析json对象:
@RequestMapping(value = "/test.htm", method = RequestMethod.POST)
@ResponseBody
public AjaxResp test(@RequestBody Dto dto){
//do something
}
页面JS:
var payload = {};
payload.dataList = ["1","2","3"];
payload.name="jack";
$.post({
url: "test.htm",
contentType:"application/json",
data: JSON.stringify(payload),
success: function (data) {
//do something
}
});
这种方式比较适合用post请求传输多个复杂字段时候使用。记得发送请求的时候设置contentType:"application/json",表示给的是json格式的数据。