这里的问题是,你(或杰克逊)需要知道需要使用哪个对象来转换请求。有两种方法:
1)使用继承。这种方法更强大,因为Jackson会为您处理所有事情,但这种方法需要添加一个标记,杰克逊将使用该标记来选择应使用哪种对象类型进行转换。不确定你可以添加这些标记,但是下面的代码应该让你知道它是如何完成的。 它非常简单 - 您只需添加@JsonTypeInfo来配置哪个字段将用作标记,而@JsonSubTypes用于定义可用于转换响应的所有类。
class ResponseA extends BaseResponse {
private String a;
}
class ResponseB extends BaseResponse {
private String b;
}
class ResponseCD extends BaseResponse {
private boolean c;
private double d;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ResponseA.class, name = "a"),
@JsonSubTypes.Type(value = ResponseB.class, name = "b"),
@JsonSubTypes.Type(value = ResponseCD.class, name = "cd")
})
class BaseResponse {
private String response;
private double delay;
private long time;
private String message;
}
public class DynamicResponseInheritance {
private static final String RESPONSE_A = "{\n" +
" \"type\": \"a\",\n" +
" \"response\": \"Success\",\n" +
" \"delay\": 0.241,\n" +
" \"time\": 125425234,\n" +
" \"message\": null,\n" +
" \"a\": \"Payloads\"\n" +
"}";
private static final String RESPONSE_B = "{\n" +
" \"type\": \"b\",\n" +
" \"response\": \"AuthFailure\",\n" +
" \"delay\": 0.112,\n" +
" \"time\": 1324515123,\n" +
" \"message\": \"Wrong password\",\n" +
" \"b\": 1234\n" +
"}";
private static final String RESPONSE_CD = "{\n" +
" \"type\": \"cd\",\n" +
" \"response\": \"Success\",\n" +
" \"delay\": 0.294,\n" +
" \"time\": 12461246123,\n" +
" \"message\": null,\n" +
" \"c\": true,\n" +
" \"d\": 245.1\n" +
"}";
public static void main(String []args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
BaseResponse responseA = objectMapper.readValue(RESPONSE_A, BaseResponse.class);
BaseResponse responseB = objectMapper.readValue(RESPONSE_B, BaseResponse.class);
BaseResponse responseCD = objectMapper.readValue(RESPONSE_CD, BaseResponse.class);
System.out.println(responseA);
System.out.println(responseB);
System.out.println(responseCD);
}
}
2)实现自定义解串器。它也非常简单,但在这种情况下,如果需要添加新类,则需要更新解串器。这种方法的好处是你不需要修改响应。
class ResponseDeserializer extends JsonDeserializer<BaseResponse> {
@Override
public BaseResponse deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) parser.getCodec();
JsonNode root = parser.getCodec().readTree(parser);
JsonNode a = root.get("a");
if (a != null) {
String content = root.toString();
return mapper.readValue(content, ResponseA.class);
}
JsonNode b = root.get("b");
if (b != null) {
String content = root.toString();
return mapper.readValue(content, ResponseB.class);
}
JsonNode c = root.get("c");
if (c != null) {
String content = root.toString();
return mapper.readValue(content, ResponseCD.class);
}
return null;
}
}
class ResponseA extends BaseResponse {
private String a;
}
class ResponseB extends BaseResponse {
private String b;
}
class ResponseCD extends BaseResponse {
private boolean c;
private double d;
}
class BaseResponse {
private String response;
private double delay;
private long time;
private String message;
}
public class DynamicResponseCustomDeserializer {
private static final String RESPONSE_A = "{\n" +
" \"response\": \"Success\",\n" +
" \"delay\": 0.241,\n" +
" \"time\": 125425234,\n" +
" \"message\": null,\n" +
" \"a\": \"Payloads\"\n" +
"}";
private static final String RESPONSE_B = "{\n" +
" \"response\": \"AuthFailure\",\n" +
" \"delay\": 0.112,\n" +
" \"time\": 1324515123,\n" +
" \"message\": \"Wrong password\",\n" +
" \"b\": 1234\n" +
"}";
private static final String RESPONSE_CD = "{\n" +
" \"response\": \"Success\",\n" +
" \"delay\": 0.294,\n" +
" \"time\": 12461246123,\n" +
" \"message\": null,\n" +
" \"c\": true,\n" +
" \"d\": 245.1\n" +
"}";
public static void main(String []args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(BaseResponse.class, new ResponseDeserializer());
objectMapper.registerModule(module);
BaseResponse responseA = objectMapper.readValue(RESPONSE_A, BaseResponse.class);
BaseResponse responseB = objectMapper.readValue(RESPONSE_B, BaseResponse.class);
BaseResponse responseCD = objectMapper.readValue(RESPONSE_CD, BaseResponse.class);
System.out.println(responseA);
System.out.println(responseB);
System.out.println(responseCD);
}
}
对代码有几个小小的改正:Response类的'response'字段应该是'String'类型,有两个'BData'类,所以第二个可能是'CData 'CData'中的''和'c'字段应该是'boolean'类型的。 –