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

如何解析带反斜杠的JSON字符串(Spring RestTemplate场景)

问题分析

服务端返回的响应并非直接的JSON对象,而是被字符串包裹的JSON结构(即外层是带转义的字符串,内部才是ServerResponse对应的JSON)。Jackson尝试将整个外层字符串直接反序列化为ServerResponse对象,但ServerResponse没有接收字符串参数的构造方法,因此抛出反序列化异常。

可行解决方案

以下方案均无需使用string.replaceAll处理转义字符:

方案1:先获取字符串响应,再二次反序列化

直接将响应先解析为字符串,再用Jackson的ObjectMapper将字符串解析为ServerResponse对象:

// 第一步:获取原始响应字符串
ResponseEntity<String> responseEntity = restTemplate.exchange(
    "some url", 
    HttpMethod.POST, 
    requestEntity, 
    String.class
);
String responseBody = responseEntity.getBody();

// 第二步:将字符串解析为ServerResponse
ObjectMapper objectMapper = new ObjectMapper();
ServerResponse serverResponse = objectMapper.readValue(responseBody, ServerResponse.class);

方案2:自定义Jackson反序列化器

给ServerResponse类添加自定义反序列化器,自动识别并处理字符串包裹的JSON结构:

  1. 编写自定义反序列化器:
public class ServerResponseDeserializer extends StdDeserializer<ServerResponse> {
    protected ServerResponseDeserializer() {
        super(ServerResponse.class);
    }

    @Override
    public ServerResponse deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // 如果当前输入是字符串类型,先解析为JSON再转成对象
        if (p.getCurrentToken() == JsonToken.VALUE_STRING) {
            String jsonStr = p.getText();
            return ctxt.readValue(jsonStr, ServerResponse.class);
        }
        // 正常JSON对象场景,直接解析
        return ctxt.readValue(p, ServerResponse.class);
    }
}
  1. 在ServerResponse类上添加反序列化器注解:
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonDeserialize(using = ServerResponseDeserializer.class) // 添加该注解
public class ServerResponse implements Serializable {
    private static final long serialVersionUID = xxxxxxxxxxxx;
    
    @JsonProperty("Status")   
    public String status;
}

之后即可直接使用原有的restTemplate.exchange调用方式,无需修改代码。

方案3:全局配置RestTemplate的消息转换器

通过自定义MappingJackson2HttpMessageConverter,给RestTemplate配置支持处理字符串包裹JSON的ObjectMapper:

RestTemplate restTemplate = new RestTemplate();

// 创建自定义ObjectMapper并注册反序列化器
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(ServerResponse.class, new ServerResponseDeserializer());
objectMapper.registerModule(module);

// 替换或添加消息转换器
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper);
restTemplate.getMessageConverters().removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);
restTemplate.getMessageConverters().add(converter);

该方案适合全局范围内需要处理此类响应的场景,一次配置即可复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:24:57