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

GraphQL响应含多余转义字符的原因及去除方法

问题:GraphQL返回的JSON字符串带多余转义字符,如何解决?

问题现象

我接收的原始无结构化JSON字符串如下:

{  
  "logo": "http://logo",  
  "name": {    
    "en": "AAA",    
    "ja": "aaa"  
  },  
  "copyrightText": {    
    "en": "AAA",    
    "ja": "aaa"  
  },  
  "help": "http://help",  
  "termsAndCondition": "http://terms"
}

期望GraphQL接口返回和上面完全一致的内容,但实际返回的响应里带了多余转义字符:

"{  \"logo\": \"http://logo\",  \"name\": {    \"en\": \"AAA\",    \"ja\": \"aaa\"  },  \"copyrightText\": {    \"en\": \"AAA\",    \"ja\": \"aaa\"  },  \"help\": \"http://help\",  \"termsAndCondition\": \"http://terms\"}"

现有配置与代码

GraphQL Schema

type Query{
    getValue: StringApiResponse
}

type StringApiResponse{
    statusCode:String!
    message:String!
    timestamp:String!
    payload:String
}

Java 查询实现

@QueryMapping(name = "getValue")
public ApiResponse getValue(){
    try {
        String value = ValueService.getValue();
        return ApiResponse.forStatus(StatusCode.S0000)
                .withMessage(StatusCode.S0000.getMessage())
                .withPayload(value);
    }
}

转义字符的来源

核心原因是GraphQL Schema里的payload被定义成了String类型:
你传入的是JSON格式的字符串,但GraphQL在序列化String类型字段时,会把字符串内部的双引号做转义处理——因为JSON规范里,字符串必须用双引号包裹,内部的双引号必须转义才能被正确识别为字符串的一部分。最终返回的payload是一个字符串类型的值,而非JSON对象,所以才会出现这些转义字符。

解决方法

方法1:修改Schema,定义结构化Payload类型(推荐)

不要用String来承载JSON结构,直接定义和原始JSON匹配的GraphQL类型,让GraphQL自动序列化正确的JSON对象:

type Query{
    getValue: StringApiResponse
}

type StringApiResponse{
    statusCode:String!
    message:String!
    timestamp:String!
    payload: Payload
}

# 对应原始JSON的结构定义
type Payload {
    logo: String
    name: LocalizedText
    copyrightText: LocalizedText
    help: String
    termsAndCondition: String
}

# 多语言文本结构
type LocalizedText {
    en: String
    ja: String
}

同时调整Java代码里的ApiResponse,把payload字段的类型从String改成对应的实体类(比如Payload类,包含logo、name等属性,name对应LocalizedText类)。这样返回时GraphQL会直接把对象序列化为JSON对象,不会产生转义。

方法2:使用JSON标量类型(适配无法修改Schema的场景)

如果不能修改Schema,可以通过引入JSON标量类型,让GraphQL把payload当作JSON对象处理:

  1. 引入支持JSON标量的依赖(比如graphql-java-extended-scalars)
  2. 修改Schema里的payload类型为JSON:
type StringApiResponse{
    statusCode:String!
    message:String!
    timestamp:String!
    payload: JSON
}
  1. 调整Java代码,把字符串解析为JSON对象再返回:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

@QueryMapping(name = "getValue")
public ApiResponse getValue(){
    try {
        String value = ValueService.getValue();
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode payloadJson = objectMapper.readTree(value);
        return ApiResponse.forStatus(StatusCode.S0000)
                .withMessage(StatusCode.S0000.getMessage())
                .withPayload(payloadJson);
    } catch (Exception e) {
        // 异常处理逻辑
        return ApiResponse.forStatus(StatusCode.ERROR)
                .withMessage("JSON解析失败");
    }
}

临时方案说明

你提到的前端用JSON.parse()解析是可行的临时办法,但这相当于把后端的问题转移到了前端处理,从接口设计的角度来说,后端返回正确的JSON结构是更规范的做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 09:13:25