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
相关产品推荐
相关产品推荐

