修改下问题,最下方为我项目的详细代码,精简了一下,去除了state属性,代码顺序最开始,基础数据类型int,从单个int到int数组,到intarraylist,
单个stirng string数组, string list, arraylist,
单个Tag对象,Tag对象数组,list,arraylist
我网上找了很多例子,例子中的controller直接接收list都是接受的字符串类型,list<string>,并没有复杂对象类型的例子
目前我所知道的两种解决办法就是
1.新建一个vo类,里面有一个list<Tag>属性,controller接受这个类
2.接受字符串,将字符串转为list
但是如果我就是想直接接受list呢?
这是我的类:
public class Tag {
int id;
String name;
int state;
}
我前台传给后台的数据格式是这个样子的
[{"id":1,"name":"123","state":0},{"id":3,"name":"456","state":0}]
我后台能否直接在入参里面用list<Tag>接收呢?
我弄了半天也不行;
那么大家平常都是如何处理的呢,都是入参接收字符串,然后用jackson等框架再转成list吗
或者是我把入参改成什么样子后台就可以接受了呢,我记得之前遇到过一次这个问题,从前台遍历对象然后弄得,但是代码没了,也忘了,但是那样弄也挺麻烦的,最简单的方法是什么呢
分割线
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件:
server:
port: 8088
spring:
thymeleaf:
mode: LEGACYHTML5
datasource:
url: jdbc:mysql://localhost:3306/ek
username: root
password: 1212
driver-class-name: com.mysql.jdbc.Driver
jpa:
database: MYSQL
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
Tag类
package com.example.demo.entity;
public class Tag {
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Tag [id=" + id + ", name=" + name + "]";
}
}
前台和后台从简单到复杂一点一点来,各阶段代码:
version 1: 单个int类型,
前台代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
<!-- 引入样式 -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<button onclick="commit()">测试</button>
<script>
function commit(){
$.ajax({
type:"post",
url: 'add',
data:{
param:1
},
success:function(data){
console.log(data);
}
})
}
</script>
</body>
</html>
后台代码:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("")
public String Hello(ModelMap map) {
return "index";
}
@ResponseBody
@RequestMapping(value = "add")
public String add(int param) {
System.out.println("param:" + param);
return "成功";
}
}
前端控制台数据格式:
param:1
后台控制台输出
param:1
version2:多个int类型;
将data:{
param:1
},
改为:
data:{
param:[1,2,3]
},
后台代码改为:
@ResponseBody
@RequestMapping(value = "add")
public String add(@RequestParam("param[]") int[] param) {
System.out.println("param:" + param);
System.out.println("param:" + Arrays.toString(param));
return "成功";
}
后台入参改为:@RequestParam("param[]") int[] param
则可以正确接收,为param则不行
前台控制台数据格式:
param[]:1
param[]:2
param[]:3
后台控制台输出:
param:[I@55a3f9bb
param:[1, 2, 3]
version3:后台使用list接受
前台代码不变,
后台代码改为:
@ResponseBody
@RequestMapping(value = "add")
public String add(@RequestParam("param[]") List<Integer> param) {
System.out.println("param:" + param);
return "成功";
}
前台数据格式:
param[]:1
param[]:2
param[]:3
后台控制台输出:
param:[1, 2, 3]
version4:后台使用arraylist接收
前台代码不变,
后台代码改为:
@ResponseBody
@RequestMapping(value = "add")
public String add(@RequestParam("param[]") ArrayList<Integer> param) {
System.out.println("param:" + param);
return "成功";
}
前台数据格式:
param[]:1
param[]:2
param[]:3
后台控制台输出:
param:[1, 2, 3]
version 5:使用字符串测试,结果和int类型结果完全一致,就不贴代码了,
version 6:使用tag类测试,传递tag对象
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
<!-- 引入样式 -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<button onclick="commit()">测试</button>
<script>
function commit(){
$.ajax({
type:"post",
url: 'add',
data:{
id:1,
name:"hello"
},
success:function(data){
console.log(data);
}
})
}
</script>
</body>
</html>
helloController:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.demo.entity.Tag;
@Controller
public class HelloController {
@RequestMapping("")
public String Hello(ModelMap map) {
return "index";
}
@ResponseBody
@RequestMapping(value = "add")
public String add(Tag tag) {
System.out.println(tag);
return "成功";
}
}
version 6结果: 后台可以成功接收Tag类的对象,
控制台输出为:Tag [id=1, name=hello]
version 7:
修改前台数据格式:
data:{
id:1,
name:"hello"
},
改为:
data:{tag:{id:1,name:'hello'}},
后台代码不变
version 7
结果:后台接受到的Tag类对象各属性为空
控制台输出为:Tag [id=0, name=null]
前台chrome控制台中记录的From data为:
tag[id]:1
tag[name]:hello
version 8 :使用tag类型的list接受数据
前台data修改为:
data:{
param:[{id:1,name:'hello'},{id:2,name:'hello'}]
},
后台代码修改为:
@ResponseBody
@RequestMapping(value = "add")
public String add(@RequestParam("param[]") List<Tag> param) {
System.out.println("param:" + param);
return "成功";
}
version 8 结果:
前台chrome显示数据格式为:
param0:1
param0:hello
param1:2
param1:hello
请求失败,前台500错误,
后台代码报错:
错误信息为:
2018-01-29 13:22:06.313 WARN 3148 --- [nio-8088-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.bind.MissingServletRequestParameterException: Required List parameter 'param[]' is not present
version 9:
ajax新增contentType,
data使用JSON.stringify格式胡
controller入参加入@requestBody注解
前台代码:
function commit(){
var param=[{id:1,name:'hello'},{id:2,name:'hello'}];
console.log(param);
console.log(JSON.stringify(param));
$.ajax({
type:"post",
url: 'add',
contentType:"application/json; charset=utf-8",
dataType:"json",
data:{
param:JSON.stringify(param)
},
success:function(data){
console.log(data);
}
})
}
后台代码:
@ResponseBody
@RequestMapping(value = "add")
public String add(@RequestBody List<Tag> param) {
System.out.println("param:" + param);
return "成功";
}
然后前台请求报400错误,
前台控制台输出位:
数据格式为:
param=%5B%7B%22id%22%3A1%2C%22name%22%3A%22hello%22%7D%2C%7B%22id%22%3A2%2C%22name%22%3A%22hello%22%7D%5D
后台报错为:
2018-01-29 13:34:06.096 WARN 3148 --- [nio-8088-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'param': was expecting ('true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'param': was expecting ('true', 'false' or 'null')
at [Source: java.io.PushbackInputStream@14a71bea; line: 1, column: 7]
2018-01-29 13:34:06.096 WARN 3148 --- [nio-8088-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'param': was expecting ('true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'param': was expecting ('true', 'false' or 'null')
at [Source: java.io.PushbackInputStream@14a71bea; line: 1, column: 7]
楼主你可以把ajax的data:{ param:JSON.stringify(param) }改成data:JSON.stringify(param);希望能帮助到你!