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.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>

下面记录的是两种接收json数据的方式。一种是把json数据接收到一个字符串中,一种是把json数据接收到Map中。根据不同的需要接收json数据,方便后续对数据的处理。

方案一:接收全部数据(String类型的变量)

把前端发送的全部数据接收到一个 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 )中。然后,通过 jacksonmapper.readValue 将json字符串转换为某个对象。

上面代码中自定义的接收数据的 DataObject 对象定义如下(只给出了所有属性):

public class DataValue {
    private String name;
    private List<Map<String, Object>> list;
}

为什么属性的类型是上面这个样子呢??

name 使用 String 类型接收,应该是很容易理解的,前端发送的数据 'testfilename.xlsx' ,就是一个简单的字符串。

那么 list 为什么使用 List<Map<String, Object>> 的类型接收呢??从外到里看。

首先,list 是一个数组,所以用 List<> 来接收。然后 <> 中要写什么呢?

{row: 1, col: 'A', value: '88'} 为例,这可以看作是一个 Map<> ,键是 String 类型,由于3个键对应的值的类型不相同,所以这里使用 Object 作为值的类型。综合起来,就是 Map<String, Object> 的类型。

因此,list 使用 List<Map<String, Object>> 可以接收到前端发送的 lsit 数据。

到这里,把前端发送的数据就接收到了某个具体的对象中了,我们也就可以把前端发送的有多个变量的数据以一个对象实例去处理。

方案二:接收每个数据(Map类型的变量)

通过 @RequestBody 将前端发送的所有数据接收到一个 Map<String, Object> 类型的变量(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";
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐