Java中无根JSON数组转POJO:API错误响应映射问题
解决方案
要解决成功响应(对象)和失败响应(无根数组)的统一映射问题,你需要通过自定义Jackson反序列化器处理两种JSON格式,并调整WebClient的错误状态码处理逻辑,具体步骤如下:
1. 补全Error实体类
确保Error类结构与第三方返回的错误字段完全匹配:
@Data @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class Error { private String errorCode; private String errorMessage; }
2. 编写自定义Jackson反序列化器
创建反序列化器,判断输入JSON的类型(对象/数组),分别解析并组装成Response对象:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectCodec; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class ResponseDeserializer extends JsonDeserializer<Response> { @Override public Response deserialize(JsonParser parser, DeserializationContext context) throws IOException { ObjectCodec codec = parser.getCodec(); JsonNode rootNode = codec.readTree(parser); Response.ResponseBuilder responseBuilder = Response.builder(); if (rootNode.isArray()) { // 失败场景:将数组解析为Error列表 List<Error> errorList = new ArrayList<>(); for (JsonNode errorNode : rootNode) { Error error = codec.treeToValue(errorNode, Error.class); errorList.add(error); } responseBuilder.errors(errorList); } else if (rootNode.isObject()) { // 成功场景:直接解析为Response对象 Response successResp = codec.treeToValue(rootNode, Response.class); responseBuilder.total(successResp.getTotal()) .errorCode(successResp.getErrorCode()) .errorMessage(successResp.getErrorMessage()) .description(successResp.getDescription()) .ordersList(successResp.getOrdersList()); } return responseBuilder.build(); } }
3. 为Response类绑定反序列化器
在Response类上添加注解,指定使用自定义反序列化器:
@JsonIgnoreProperties(ignoreUnknown = true) @Data @Builder @JsonDeserialize(using = ResponseDeserializer.class) // 绑定自定义反序列化器 public class Response { private int total; private String errorCode; private String errorMessage; private String description; private List<Order> ordersList; private List<Error> errors; }
4. 调整WebClient的错误处理逻辑
第三方失败响应通常返回非200状态码,默认WebClient会抛出异常,需通过onStatus捕获错误状态码,将响应体解析为Response后返回,实现统一处理:
Response response = webClient .post() .uri(url, uri -> uri.queryParam(Constants.QUERY_PARAM).build()) .header("Content-Type", "application/json") .bodyValue(request) .retrieve() // 捕获所有错误状态码,解析响应体为Response .onStatus(HttpStatus::isError, clientResponse -> clientResponse.bodyToMono(Response.class) .flatMap(Mono::just) ) .bodyToMono(Response.class) .block();
验证逻辑
- 当API返回200 OK的对象JSON时,反序列化器会填充
ordersList等业务字段,errors字段为null - 当API返回失败的数组JSON时,反序列化器会将数组解析为
errors列表,其他字段保持默认值(或null)
内容的提问来源于stack exchange,提问作者Loren
相关产品推荐
相关产品推荐

