Spring Boot 如何接收并处理不确定类型的请求参数?

简介: 在 Spring Boot 中,当需要处理结构不确定的 JSON 数据时,可以使用 `Map` 类型灵活接收键值对数据。对于更复杂的场景,可通过 Jackson 注解支持多态类型、自定义反序列化器,或在接收后动态解析 JSON 数据,提升处理灵活性和扩展性。
  • 使用 Map 类型接收未知结构的 JSON 数据
  • 在 Spring Boot 中,当 JSON 数据结构不确定时,可以使用 Map 类型来接收。因为 Map 可以存储键值对的形式,能够灵活地处理各种不同的字段组合。
  • 例如,创建一个请求体对应的类,其中用 Map 来存储不确定类型的字段:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class RequestBody {
    // 已知字段
    private String id;
    private String name;

    // 不确定类型的字段,用 Map 存储
    private Map<String, Object> data;

    // getter 和 setter 方法
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }
}
  • 然后在控制器中使用这个请求体类来接收请求:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@PostMapping("/example")
public ResponseEntity<String> handleRequest(@RequestBody RequestBody requestBody) {
    // 可以通过 requestBody.getData() 获取 data 字段中的内容
    // 根据实际业务逻辑处理 Map 中的数据
    return ResponseEntity.ok("Request received");
}
  • 使用 Jackson 的注解进行多态类型处理
  • 如果你能确定 data 字段可能包含的几种特定的复杂对象类型,可以使用 Jackson 的注解来处理多态类型。这需要创建一个基类,并使用注解来指定可能的子类型。
  • 例如,创建一个基类:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = TypeA.class, name = "typeA"),
    @JsonSubTypes.Type(value = TypeB.class, name = "typeB")
})
public abstract class Data {
    // 公共字段
}
  • 然后创建具体的子类:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class TypeA extends Data {
    // 特有字段
    private String fieldA1;
    private String fieldA2;

    // getter 和 setter 方法
}

public class TypeB extends Data {
    // 特有字段
    private int fieldB1;
    private boolean fieldB2;

    // getter 和 setter 方法
}
  • 在请求体类中使用这个基类:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class RequestBody {
    // 已知字段
    private String id;
    private String name;

    // data 字段是一个复杂对象数组,使用 Data 类型
    private Data[] data;

    // getter 和 setter 方法
}
  • 这样,当 JSON 数据中的 data 字段包含特定的类型标记(如上面例子中的 type 字段)时,Jackson 就能正确地将其反序列化为对应的子类对象。
  • 使用自定义的反序列化器
  • data 字段的结构非常复杂,且不能用简单的多态类型来描述时,可以创建自定义的反序列化器。
  • 首先,创建一个自定义的反序列化器类,继承 JsonDeserializer

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class CustomDataDeserializer extends JsonDeserializer<Object> {
    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // 获取 JSON 节点
        JsonNode node = p.getCodec().readTree(p);
        // 根据实际的业务逻辑和 JSON 结构来判断和转换数据
        // 例如,根据某个字段来判断类型
        if (node.has("specificFieldA")) {
            // 反序列化为特定的类 TypeA
            ObjectMapper mapper = (ObjectMapper) p.getCodec();
            return mapper.convertValue(node, TypeA.class);
        } else if (node.has("specificFieldB")) {
            // 反序列化为特定的类 TypeB
            ObjectMapper mapper = (ObjectMapper) p.getCodec();
            return mapper.convertValue(node, TypeB.class);
        } else {
            // 默认处理或其他逻辑
            return null;
        }
    }
}
  • 然后在请求体类中使用这个自定义反序列化器来处理 data 字段:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class RequestBody {
    // 已知字段
    private String id;
    private String name;

    // 使用自定义反序列化器处理 data 字段
    @JsonDeserialize(using = CustomDataDeserializer.class)
    private Object data;

    // getter 和 setter 方法
}
  • 在接收后动态解析 JSON
  • 如果在接收请求后,想在代码中动态解析 data 字段中的 JSON 数据,可以使用 ObjectMapperdata 字段中的内容转换为 JsonNode,然后根据需要进行解析。
  • 例如,修改请求体类中的 data 字段为 Object 类型(或者 String 类型,如果希望先接收为 JSON 字符串):

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
public class RequestBody {
    // 已知字段
    private String id;
    private String name;

    // data 字段接收为对象,可以是 Map、List 或其他类型
    private Object data;

    // getter 和 setter 方法
}
  • 在控制器中处理:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@PostMapping("/example")
public ResponseEntity<String> handleRequest(@RequestBody RequestBody requestBody) throws IOException {
    // 使用 ObjectMapper 将 data 转换为 JsonNode
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode dataNode = objectMapper.valueToTree(requestBody.getData());

    // 动态解析 dataNode 中的内容
    // 例如,遍历数组
    if (dataNode.isArray()) {
        for (JsonNode element : dataNode) {
            // 处理每个元素
            if (element.has("fieldA1")) {
                // 按照 TypeA 的逻辑处理
            } else if (element.has("fieldB1")) {
                // 按照 TypeB 的逻辑处理
            }
        }
    }

    return ResponseEntity.ok("Request received");
}
  • 这种方式比较灵活,可以在代码中根据不同的业务规则动态地处理 data 字段中的内容,但需要自己编写更多的解析逻辑。


转载来源:https://juejin.cn/post/7502642062581039123

相关文章
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
2542 0
|
6月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
539 4
|
6月前
|
XML JSON Java
【SpringBoot(三)】从请求到响应再到视图解析与模板引擎,本文带你领悟SpringBoot请求接收全流程!
Springboot专栏第三章,从请求的接收到视图解析,再到thymeleaf模板引擎的使用! 本文带你领悟SpringBoot请求接收到渲染的使用全流程!
473 3
|
前端开发 Java API
Spring Boot之Spring MVC基于注解的控制器(RequestMapping注解类型 重定向与转发 依赖注入)
Spring Boot之Spring MVC基于注解的控制器(RequestMapping注解类型 重定向与转发 依赖注入)
396 0
|
Java Spring
SpringBoot接收参数的方式
本文介绍了Java Spring Boot中处理GET请求的多种方式。可以使用方法参数直接接收,或者通过`@RequestParam`注解指定必传参数。此外,可以用实体类接收多个相关参数,但不能同时使用`@RequestParam`。还可以通过`HttpServletRequest`对象获取参数,或利用`@PathVariable`接收路径变量。对于数组和集合参数,需注意使用`@RequestParam`注解。
1601 1
|
XML JavaScript 前端开发
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
1119 2
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
350 8
|
Java Spring 容器
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
这篇文章讨论了在Spring Boot 3.2.1版本中,同名同类型的bean和@Service注解类之间冲突的问题得到了解决,之前版本中同名bean会相互覆盖,但不会在启动时报错,而在配置文件中设置`spring.main.allow-bean-definition-overriding=true`可以解决这个问题。
834 0
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
|
关系型数据库 MySQL Java
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
353 0
|
安全 算法 Java
强大!基于Spring Boot 3.3 六种策略识别上传文件类型
【10月更文挑战第1天】在Web开发中,文件上传是一个常见的功能需求。然而,如何确保上传的文件类型符合预期,防止恶意文件入侵,是开发者必须面对的挑战。本文将围绕“基于Spring Boot 3.3 六种策略识别上传文件类型”这一主题,分享一些工作学习中的技术干货,帮助大家提升文件上传的安全性和效率。
878 0

热门文章

最新文章