gpt4 book ai didi

java - MessageBodyReader 如何知道泛型类型是什么?

转载 作者:行者123 更新时间:2023-12-01 18:05:01 25 4
gpt4 key购买 nike

我有一个MessageBodyReader具有以下类:

@Provider
@Consumes(MediaType.APPLICATION_JSON)
public class TransactionMessageBodyReader implements MessageBodyReader<Transaction<Customer>>

boolean isReadable(Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType)

我有以下 REST 端点:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("trans")
public Response checkStatus(Transaction<Customer> transaction) { ... }

在我的调试器中,我在 isReadable 上有一个断点它在调用 checkStatus 之前到达断点方法。目前很好。我可以在调试器中看到 genericTypeTransaction<Customer> ...换句话说,它知道类型信息。当Java类型删除将其删除为Transaction时,它怎么可能知道类型信息?在运行时?我看到 genericTypeParameterizedType 组成我相信它用于传递类型信息(以解决类型删除问题)。但是, Jersey 如何填充 genericType自动地?因为除了上面发布的方法 header 之外,我从未指定过类型信息。

另外,第二个问题:如果 Jersey “自动”了解我的类型,为什么我需要 MessageBodyReader根本吗?是否有一些更简单的方法可以将泛型与 Jersey/REST 端点一起使用并使其“正常工作”?

最佳答案

看看javadoc .

genericType - the type of instance to be produced. E.g. if the message body is to be converted into a method parameter, this will be the formal type of the method parameter as returned by Method.getGenericParameterTypes.

类、方法和字段中的通用参数化在相应的.class 文件中维护。这显然是编译所必需的。如果不是这种情况,您将无法将 Java 类打包并用作库。

反射公开此类型信息(以及更多信息)。

Jersey 基本上会扫描您的类中的处理程序方法,用 @POST 等注释的方法,并检索相应的 Method对象。一旦有了,它就可以使用 Method#getGenericParameterTypes()

Returns an array of Type objects that represent the formal parameter types, in declaration order, of the executable represented by this object. Returns an array of length 0 if the underlying executable takes no parameters.

If a formal parameter type is a parameterized type, the Type object returned for it must accurately reflect the actual type parameters used in the source code.

换句话说,Type 必须同时表示参数的原始类型及其参数化(如果有的话)。

因此 Jersey 检索这些类型并将它们输入到您的 MessageBodyReader 中。期望您的实现应该能够处理genericType

我不太了解 Jersey,但如果它遵循与 Spring MVC 相同的策略,它将简单地迭代所有已注册的 MessageBodyReader 实例。它实际上并不关心它的类型(例如,您的TransactionMessageBodyReader),这就是它依赖于isReadable的原因。理论上,它可以保留类型到 MessageBodyReader 实现的映射,但这最终会变得笨拙且不太灵活。无论如何,应用程序通常不会有那么多可以序列化的类型/格式,因此迭代一些对象并不是什么大问题。

<小时/>

自 Java 8 起,您还可以访问 Executable#getParameters (MethodExecutable 的子类型)。

<小时/>

这是 Jersey 可以做什么的示例

public class StackOverflow {
public static void main(String[] args) throws Exception {
Method method = StackOverflow.class.getDeclaredMethod("method", List.class);
Type[] parameterTypes = method.getGenericParameterTypes();
for (Type parameterType : parameterTypes) {
System.out.println(parameterType.getClass());
System.out.println(parameterType);
ParameterizedType parameterizedType = (ParameterizedType) parameterType;
System.out
.println(parameterizedType.getRawType().getTypeName() + "<" + parameterizedType.getActualTypeArguments()[0].getTypeName() + ">");
}
}

public String method(List<StackOverflow> parameter) {
return "example";

}
}

打印

class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
java.util.List<com.example.StackOverflow>
java.util.List<com.example.StackOverflow>

关于java - MessageBodyReader 如何知道泛型类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37219300/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com