You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中字符串[]转JsonNode出现额外引号致测试失败

解决测试场景下JsonNode转换出现额外引号的问题

我帮你排查了下问题的根源,咱们一步一步来解决:

问题出在哪?

你测试时遇到的额外引号,核心原因是测试代码里把字符串"[]"当成了JSON字符串值处理,而Postman里传的是真正的JSON空数组[]:

  • Postman请求里的"labels":[],Jackson会解析成ArrayNode(数组类型的JsonNode),调用它的toString()方法会直接输出"[]",符合你的预期。
  • 但测试代码里用了mapper.valueToTree(jsonString),这里的jsonString是Java字符串"[]",Jackson会把它包装成TextNode(文本类型的JsonNode),调用toString()时就会给整个字符串加上双引号,变成""[]""——这就是你看到的额外引号的来源。

怎么修复?

有两种简单的修复方式,选适合你的就行:

方式1:直接创建空数组节点(推荐)

既然你要模拟Postman传的空数组,直接用Jackson创建ArrayNode就好,完全贴合真实请求的情况:

@Test
public void getEmptyDocumentException() throws InvalidBarcodeException, EmptyStringException, InvalidBarcodeGeometryException, EmptyFieldException, TemplateNotFoundException, InvalidBarcodeStrategyException {
    final String templateId = "fj2j931j2ijd1";
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(JsonParser.Feature.ALLOW_MISSING_VALUES);
    
    // 直接创建空数组节点,和Postman传的[]一致
    JsonNode labels = mapper.createArrayNode();
    
    PostLabelDTO dto = new PostLabelDTO(templateId, labels);
    final Document document = new Document(dto, templateRepository);
    
    Exception resultingException = null;
    try {
        document.getPDF();
    } catch (Exception e) {
        resultingException = e; // 这里要给resultingException赋值,之前的代码漏了!
        e.printStackTrace();
    }
    assertThat(resultingException).isExactlyInstanceOf(EmptyDocumentException.class);
}

另外注意:你原来的测试代码里resultingException在catch块里没赋值,会导致断言永远失败,我已经一起修正了这个小问题。

方式2:用readTree解析字符串

如果你一定要从字符串"[]"生成JsonNode,别用valueToTree,改用readTree——它会把字符串当成JSON内容解析,而不是把字符串本身当成JSON值:

JsonNode labels = mapper.readTree(jsonString); // 这样得到的是ArrayNode,不是TextNode

额外优化建议

看你的DTO代码,你把JsonNode转成String存起来了,如果业务上不需要提前转成String,建议直接保留JsonNode类型,这样不仅避免了toString的引号问题,后续操作JSON也更灵活:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;

public class PostLabelDTO {
    private final String templateId;
    private final JsonNode labels; // 保留JsonNode类型

    @JsonCreator
    public PostLabelDTO(
            final @JsonProperty("templateId") String templateId,
            final @JsonProperty("labels") JsonNode labels
    ) {
        this.templateId = templateId;
        this.labels = labels; // 不再转成String
    }

    public String getId() {
        return templateId;
    }

    public JsonNode getData() {
        return labels; // 返回JsonNode
    }
}

内容的提问来源于stack exchange,提问作者user2520459

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:07:21