将 JSON 字符串反序列化为包装通用 class 的 class
Deserialize a JSON string to a class that wrapps a generic class
首先是一些上下文。
我有这个包装器 class:
public class ResponseEntity<T> {
private String code;
private String message;
private T data;
public ResponseEntity(String code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public ResponseEntity(String code, String message) {
this.code = code;
this.message = message;
this.data = null;
}
...getters...
}
然后我有class我在里面用:
public class Foo {
private String name;
private String age;
public Foo(String name, String age) {
this.name = name;
this.age = age;
}
...getters...
}
我使用 AWS Lambda,因此 ResponseEntity 在 AWS Lambda 响应 class 内的 body
字段中序列化:
some-lambda-handler-class.java
public APIGatewayProxyResponseEvent handleRequest(String name, String age) {
Foo foo = new Foo(name, age);
ResponseEntity<Foo> fooResponse = new ResponseEntity("code", "msg", foo);
String body = gson.toJson(fooResponse);
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setBody(body);
return response;
}
问题出在我测试处理程序时 class:
some-lambda-handler-class-test.java
@Test
public void test() {
APIGatewayProxyResponseEvent response = myHandler.handleRequest("foo", "bar");
ResponseEntity<Foo> fooResponse = gson.fromJson(response.getBody(), ResponseEntity.class);
assertThat(fooResponse.getCode(), is("code")); // This assert is Ok
assertThat(fooResponse.getMessage(), is("msg")); // This assert is Ok
assertThat(fooResponse.getData().getName(), is("foo")); // this throws an error
// Error is: java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class Foo (com.google.gson.internal.LinkedTreeMap and Foo are in unnamed module of loader 'app')
assertThat(fooResponse.getData().getAge(), is("bar"));
}
我从这个错误中了解到,我必须以某种方式告诉 gson 我想从 json 反序列化的 class 是一个 ResponseEntity<Foo>.class
,所以使用 LinkedTreeMap
作为 data
字段,使用 Foo
.
但我不知道该怎么做。因为如果我这样做:
ResponseEntity<Foo> fooResponse = gson.fromJson(response.getBody(), ResponseEntity<Foo>.class);
// The "ResponseEntity<Foo>.class" part shows an error ("Cannot select from parameterized type")
所以问题是,
如何告诉 Gson 将 JSON 字符串反序列化为 ResponseEntity<Foo>
class?
提前致谢。
你必须使用
gson.fromJson(response.getBody(), new TypeToken<ResponseEntity<Foo>>() {}.getType());
因为您使用了包装 class
ResponseEntity<Foo>.class
不可能,因为 .class
忽略 <> parms
首先是一些上下文。
我有这个包装器 class:
public class ResponseEntity<T> {
private String code;
private String message;
private T data;
public ResponseEntity(String code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public ResponseEntity(String code, String message) {
this.code = code;
this.message = message;
this.data = null;
}
...getters...
}
然后我有class我在里面用:
public class Foo {
private String name;
private String age;
public Foo(String name, String age) {
this.name = name;
this.age = age;
}
...getters...
}
我使用 AWS Lambda,因此 ResponseEntity 在 AWS Lambda 响应 class 内的 body
字段中序列化:
some-lambda-handler-class.java
public APIGatewayProxyResponseEvent handleRequest(String name, String age) {
Foo foo = new Foo(name, age);
ResponseEntity<Foo> fooResponse = new ResponseEntity("code", "msg", foo);
String body = gson.toJson(fooResponse);
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setBody(body);
return response;
}
问题出在我测试处理程序时 class:
some-lambda-handler-class-test.java
@Test
public void test() {
APIGatewayProxyResponseEvent response = myHandler.handleRequest("foo", "bar");
ResponseEntity<Foo> fooResponse = gson.fromJson(response.getBody(), ResponseEntity.class);
assertThat(fooResponse.getCode(), is("code")); // This assert is Ok
assertThat(fooResponse.getMessage(), is("msg")); // This assert is Ok
assertThat(fooResponse.getData().getName(), is("foo")); // this throws an error
// Error is: java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class Foo (com.google.gson.internal.LinkedTreeMap and Foo are in unnamed module of loader 'app')
assertThat(fooResponse.getData().getAge(), is("bar"));
}
我从这个错误中了解到,我必须以某种方式告诉 gson 我想从 json 反序列化的 class 是一个 ResponseEntity<Foo>.class
,所以使用 LinkedTreeMap
作为 data
字段,使用 Foo
.
但我不知道该怎么做。因为如果我这样做:
ResponseEntity<Foo> fooResponse = gson.fromJson(response.getBody(), ResponseEntity<Foo>.class);
// The "ResponseEntity<Foo>.class" part shows an error ("Cannot select from parameterized type")
所以问题是,
如何告诉 Gson 将 JSON 字符串反序列化为 ResponseEntity<Foo>
class?
提前致谢。
你必须使用
gson.fromJson(response.getBody(), new TypeToken<ResponseEntity<Foo>>() {}.getType());
因为您使用了包装 class
ResponseEntity<Foo>.class
不可能,因为 .class
忽略 <> parms