Spring boot 从Mono<String>中提取JSON属性返回

举报
林欣 发表于 2025/08/09 22:36:51 2025/08/09
【摘要】 如果你想从 Mono<String>(JSON 字符串)中提取例如 data[0].name 并返回给前端,可以使用 Reactor 的 map 操作符 结合 JSON 解析库(如 Jackson 或 Gson)来处理。以下是修改后的代码: 方案 1:使用 Jackson 解析 JSON(推荐)Spring Boot 默认集成 Jackson,可以直接解析 JSON:import com.f...

如果你想从 Mono<String>(JSON 字符串)中提取例如 data[0].name 并返回给前端,可以使用 Reactor 的 map 操作符 结合 JSON 解析库(如 JacksonGson)来处理。以下是修改后的代码:


方案 1:使用 Jackson 解析 JSON(推荐)

Spring Boot 默认集成 Jackson,可以直接解析 JSON:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Mono;

@ApiOperation(value = "获取当前用户的最近会话名称")
@GetMapping(value = "/api/v1/ai/chat-stream/conversations/last/name")
public Mono<String> getLastConversationName() {
    return copilotApiService
        .getConversations(null, 1, "-updated_at") // 返回 Mono<String>(JSON)
        .map(json -> {
            try {
                ObjectMapper mapper = new ObjectMapper();
                JsonNode rootNode = mapper.readTree(json); // 解析 JSON
                String name = rootNode.path("data").get(0).path("name").asText(); // 提取 name
                return name; // 返回单个字符串
            } catch (Exception e) {
                throw new RuntimeException("Failed to parse JSON", e);
            }
        });
}

访问 /api/v1/ai/chat-stream/conversations/last/name 会返回

"战国灭亡顺序表格 📊"

方案 2:使用 Gson 解析 JSON

如果项目使用 Gson,可以这样改:

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import reactor.core.publisher.Mono;

@ApiOperation(value = "获取当前用户的最近会话名称")
@GetMapping(value = "/api/v1/ai/chat-stream/conversations/last/name")
public Mono<String> getLastConversationName() {
    return copilotApiService
        .getConversations(null, 1, "-updated_at")
        .map(json -> {
            JsonObject rootObject = JsonParser.parseString(json).getAsJsonObject();
            String name = rootObject.getAsJsonArray("data")
                                   .get(0)
                                   .getAsJsonObject()
                                   .get("name")
                                   .getAsString();
            return name;
        });
}

方案 3:定义 DTO 类(更规范)

如果 JSON 结构复杂,建议定义 DTO 类,用 ObjectMapper 自动映射:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

// 定义 DTO 类
public class ConversationResponse {
    private int limit;
    private boolean has_more;
    private List<ConversationData> data;

    // getters & setters

    public static class ConversationData {
        private String id;
        private String name;
        // 其他字段...

        // getters & setters
    }
}

// 控制器代码
@ApiOperation(value = "获取当前用户的最近会话名称")
@GetMapping(value = "/api/v1/ai/chat-stream/conversations/last/name")
public Mono<String> getLastConversationName() {
    return copilotApiService
        .getConversations(null, 1, "-updated_at")
        .map(json -> {
            ObjectMapper mapper = new ObjectMapper();
            ConversationResponse response = mapper.readValue(json, ConversationResponse.class);
            return response.getData().get(0).getName(); // 直接返回 name
        });
}

关键点总结

  1. map 操作符:用于处理 Mono 中的数据。
  2. JSON 解析
    • 简单场景:用 JacksonGson 手动解析。
    • 复杂场景:定义 DTO 类,自动映射。
  3. 异常处理:如果 JSON 解析失败,可以抛出 RuntimeException 或自定义异常。

最终推荐代码(Jackson + DTO)

@ApiOperation(value = "获取当前用户的最近会话名称")
@GetMapping(value = "/api/v1/ai/chat-stream/conversations/last/name")
public Mono<String> getLastConversationName() {
    return copilotApiService
        .getConversations(null, 1, "-updated_at")
        .map(json -> {
            try {
                ObjectMapper mapper = new ObjectMapper();
                ConversationResponse response = mapper.readValue(json, ConversationResponse.class);
                return response.getData().get(0).getName();
            } catch (Exception e) {
                return "默认名称"; // 或者抛出异常
            }
        });
}

这样就能 只返回 name 字段 给前端,代码也更健壮。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。