我想挂钩杰克逊的反序列化,以选择反序列化不同于提供的JSON文档的JSON文档.这似乎是一个非常奇怪的用例,所以让我解释一下.
我正在使用Amazon SQS Extended客户端在S3上放置对于SQS而言太大的消息,并通过SQS显示如下所示的消息
["com.amazon.sqs.javamessaging.MessageS3Pointer",{"s3BucketName":"my-bucket","s3Key":"f5a0fa29-7f9c-4852-8bbb-53697799efe2"}]
Run Code Online (Sandbox Code Playgroud)
一个弹性beanstalk工作者正在监听另一端,这意味着这些消息被POST到我的应用程序维护的Jersey端点.由于这些消息是POST而不是使用SQS receiveMessage调用,因此扩展客户端不会从S3本身获取消息.
我认为制作一个自定义的自定义将是非常聪明的JsonDeserializer,看看它是否是一个S3指针,下载该文件,并反序列化它.否则,只需反序列化提供的消息.然而,这并不像我希望的那样顺利.
这是我到目前为止:
public class SQSS3Deserializer<T> extends JsonDeserializer<T> {
private static final String s3PointerHeader = "com.amazon.sqs.javamessaging.MessageS3Pointer";
private Class<T> type;
private ObjectMapper mapper = new ObjectMapper();
public SQSS3Deserializer() {
super();
type = getParameterizedTypeArgument();
}
@Override
public T deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
if (jp.isExpectedStartArrayToken()) {
jp.nextToken();
if (s3PointerHeader.equals(jp.getValueAsString())) {
jp.nextToken();
S3Pointer p = jp.readValueAs(S3Pointer.class);
return mapper.readValue(S3Utils.getInputStream(p.s3BucketName, p.s3Key), type);
}
}
return jp.readValueAs(type);
}
@SuppressWarnings("unchecked")
protected Class<T> getParameterizedTypeArgument() {
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
static private class S3Pointer {
public String s3BucketName;
public String s3Key;
}
}
Run Code Online (Sandbox Code Playgroud)
对于每个要反序列化的POJO,我必须使用正确的泛型特化创建一个空子类,例如:
public class POJOS3Deserializer extends SQSS3Deserializer<POJO> {}
Run Code Online (Sandbox Code Playgroud)
我还需要将JsonDeserializer注释添加到类中
@JsonDeserialize(using=POJOS3Deserializer.class)
public class POJO { ... }
Run Code Online (Sandbox Code Playgroud)
但是,这样做会导致堆栈溢出错误,因为它会在调用时不断重新输入我的反序列化器,JsonParser.readValueAs()因为readValueAs会查看JsonDeserialize注释.
所以,我有两个问题:
谢谢
| 归档时间: |
|
| 查看次数: |
604 次 |
| 最近记录: |