java 接收参数或数据的方式可以看另外一篇 java接收数据的方式
这篇文章记录的是前后端在交互时,数据以json的格式进行传递,一般会使用第三种方案接收多个数据,主要是记录使用 @RequestBody
接收前端数据的方案,前两种只是可以接收到数据,一般使用第三种接收数据。
本文章中的例子,前端使用的语言是vue,后端使用的语言是 java。整篇文章使用的数据例子(json格式)如下:
{
"name": "testfilename.xlsx",
"list": [
{
"row": "1",
"col": "A",
"value": "77"
},
{
"row": "2",
"col": "B",
"value": "88"
},
{
"row": "3",
"col": "C",
"value": "99"
},
]
}
前端发送数据的格式,以 json 的格式传递数据。前端核心代码如下:
let data = {
name: 'testfilename.xlsx',
list: [
{ row: 1, col: 'A', value: '88' },
{ row: 2, col: 'B', value: '99' },
{ row: 3, col: 'C', value: '77' },
]
} // 带发送的数据
this.axios.post('/test', data).then((res) => {
console.log(res)
}, (error) => {
console.log(error)
})
这里后端使用了 jackson
工具处理 json 数据。所以,先在 pom.xml
中导入依赖
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.12.3version>
dependency>
下面记录的是两种接收json数据的方式。一种是把json数据接收到一个字符串中,一种是把json数据接收到Map中。根据不同的需要接收json数据,方便后续对数据的处理。
把前端发送的全部数据接收到一个 String
类型的变量( params
)中,然后通过json转换把变量 (params
) 的所有值存储到一个对象 (DataObject
) 中,以方便后续可能会以对象的形式对从前端接收的数据进行处理。
@PostMapping("/test")
public String test(@RequestBody String params) throws IOException {
System.out.println("params: " + params); // 打印接收到的数据
ObjectMapper mapper = new ObjectMapper(); // 创建ObjectMapper对象
DataObject value = mapper.readValue(params, DataObject.class);//反序列化JSON到对象。
System.out.println("value: " + value.toString()); // 打印转换之后的对象的信息
return "ok";
}
通过 @RequestBody
将前端发送的所有数据接收到一个 String
类型的变量( params
)中。然后,通过 jackson
的 mapper.readValue
将json字符串转换为某个对象。
上面代码中自定义的接收数据的 DataObject
对象定义如下(只给出了所有属性):
public class DataValue {
private String name;
private List<Map<String, Object>> list;
}
为什么属性的类型是上面这个样子呢??
name
使用 String
类型接收,应该是很容易理解的,前端发送的数据 'testfilename.xlsx'
,就是一个简单的字符串。
那么 list
为什么使用 List
的类型接收呢??从外到里看。
首先,list
是一个数组,所以用 List<>
来接收。然后 <>
中要写什么呢?
以 {row: 1, col: 'A', value: '88'}
为例,这可以看作是一个 Map<>
,键是 String
类型,由于3个键对应的值的类型不相同,所以这里使用 Object
作为值的类型。综合起来,就是 Map
的类型。
因此,list
使用 List
可以接收到前端发送的 lsit
数据。
到这里,把前端发送的数据就接收到了某个具体的对象中了,我们也就可以把前端发送的有多个变量的数据以一个对象实例去处理。
通过 @RequestBody
将前端发送的所有数据接收到一个 Map
类型的变量(params
)中。然后,从变量(params
)中获取需要的键对应的值。
@PostMapping("/test")
public String test(@RequestBody Map<String, Object> params) throws IOException {
// 获取参数 params 中键为 name 的值
String name = (String) params.get("name");
// 获取参数 params 中键为 list 的值
List<Map<String, Object>> list = (List<Map<String, Object>>) params.get("list");
System.out.println("name: " + name); // 打印接收到的 name 变量的值
System.out.println("list: " + list.toString()); // 打印接收到的 list 变量的值
return "ok";
}
当然,也可以把 list
数据存到一个对象中,因为有些情况可能需要把json中的部分数据转换到对象中。
如果有这么一种情况,我只需要把前端的 {row: 1, col: 'A', value: '88'}
这部分封装为一个对象,那么,就需要单独获取到json中的某些值。
抽象出来的对象定义如下(只给出了属性):
public class MapValue {
private Integer rowIndex;
private String colIndex;
private String value;
}
那么接收json数据的代码就可以修改为以下:
@PostMapping("/test")
public String test(@RequestBody Map<String, Object> params) throws IOException {
String name = (String) params.get("name");
List<MapValue> list = (List<MapValue>) params.get("list");
System.out.println("name: " + name);
System.out.println("list: " + list.toString());
return "ok";
}
Java 需要创建一个对象(比如创建了一个 DataObject
对象)用于接收前端的数据。这个对象 DataObject
是一个实体类,只包含属性和 get/set
方法。同时这个接收对象的属性名和前端传递的数据名要一一对应,名字不同也不会接收到。以前面传递的数据为例,创建一个对象用来接收数据,对象如下:
/**
name: 'testfilename.xlsx',
list: [
{ row: 1, col: 'A', value: '88' },
{ row: 2, col: 'B', value: '99' },
{ row: 3, col: 'C', value: '77' },
]
*/
public class DataObject {
private String name,
List<Cell> cellList;
// 省略 get/set/toString 方法
}
/**
{ row: 1, col: 'A', value: '88' }
这个数据可以使用三元组定义,也可以重新创建一个对象
*/
public class Cell {
private String row;
private String col;
private String value;
// 省略 get/set/toString 方法
}
这样,把前端发送的全部数据接收到一个对象 DataObject
中
@PostMapping("/test")
public String test(@RequestBody DataObject data) throws IOException {
System.out.println("data: " + data.toString()); // 打印接收到的数据
return "ok";
}