gpt4 book ai didi

java - MessageBody写入器/读取器

转载 作者:太空宇宙 更新时间:2023-11-04 06:24:29 24 4
gpt4 key购买 nike

我正在尝试让 Jersey 支持 GSON,为此我读到我需要实现自定义 MessageBodyWriterMessageBodyReader

现在我的问题是我找不到这两个接口(interface)的任何明确定义。

来自文档:

public interface MessageBodyWriter<T>

Contract for a provider that supports the conversion of a Java type to a stream. To add a MessageBodyWriter implementation, annotate the implementation class with @Provider. A MessageBodyWriter implementation may be annotated with Produces to restrict the media types for which it will be considered suitable.

public interface MessageBodyReader<T>

Contract for a provider that supports the conversion of a stream to a Java type. A MessageBodyReader implementation may be annotated with Consumes to restrict the media types for which it will be considered suitable. Providers implementing MessageBodyReader contract must be either programmatically registered in a JAX-RS runtime or must be annotated with @Provider annotation to be automatically discovered by the JAX-RS runtime during a provider scanning phase.

谁能给我解释一下具体是什么意思吗?

为什么我需要在 GSON 支持的情况下实现它们?

谢谢。

最佳答案

提供商契约(Contract)...

仅指接口(interface)公开的方法的集合。如果我们实现接口(interface),我们必须实现一组契约方法,框架将使用这些方法来利用我们的实现

MessageBodyWriter - 支持将 Java 类型转换为流的提供者的合约 - 从我们的 JAX-RS 资源方法中,我们返回带有实体主体(它是 Java 对象)或 Java 对象的 Response。消息正文编写器负责将此 Java 对象转换为响应的输出流。例如(仅供玩耍,假设我们尚未支持 JAXB 编码)

@Override
public void writeTo(Customer c, Class<Customer> type,
Type genericType, Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String,Object> httpHeaders,
OutputStream entityStream) {

JAXBContext context = JAXBContext.newInstance(type);
Marshaller marsaller = context.createMarshaller();
marshaller.marshal(c, entityStream);
}

您可以看到我创建了 Marshaller,它将 Customer 对象编码到(由框架)提供的 OutputStream

MessageBodyReader - 支持将流转换为 Java 类型的提供者的契约(Contract) - 与编写器相同,但这次过程相反。在将 Java 类型传递给我们的 JAX-RS 资源方法之前,需要对其进行转换。例如

@Override
public Customer readFrom(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String,String> httpHeaders,
InputStream entityStream) throws IOException,
WebApplicationException {

JAXBContext context = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = context.createUnmarshaller();

return (Customer)unarshaller.unmarshal(entityStream);
}

MessageBodyWriter...

To add a MessageBodyWriter implementation, annotate the implementation class with @Provider. A MessageBodyWriter implementation may be annotated with Produces to restrict the media types for which it will be considered suitable

JAX-RS 具有“提供者”的概念。您可以将其视为组件的另一个词。当我们使用 @Provider 注释 JAX-RS 实现的类时,它就可以成为由框架管理的组件。

对于MessageBodyWriters/MessageBodyReaders,有一个特定的算法来确定每个请求/响应将使用哪个写入器/读取器。基本上发生的事情是 JAX-RS 根据 @Produces 注释匹配来计算列表或编写器。例如,如果我们的资源方法或资源类用 @Produces(MediaType.APPLICATION_XML) 进行注释,并且我们的提供者(编写器)也用此注释,那么我们的编写器将被放入此列表中。然后通过某种算法对这些提供者进行排序。最后,每个写入器都会调用 isWritable 方法,直到其中一个写入器返回 true 为止。这就是将要使用的作家。例如

@Provider
@Produces(MediaType.APPLICATION_XML)
public class MyJAXBMessageBodyWriter
implements MessaheBodyWriter<Customer> {
@Override
public boolean isWriteable(Class<Customer> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {

return type == Customer.class;
}
}

@GET
@Produces(MediaType.APPLICATION_XML)
public Response getCustomer() {
Customer customer = customerService.getCustomer();
return Response.ok(customer).build();
}

这两个将被匹配,我们的编写器将用于转换我们的 Customer 对象

MessageBodReader...

A MessageBodyReader implementation may be annotated with Consumes to restrict the media types for which it will be considered suitable. Providers implementing MessageBodyReader contract must be either programmatically registered in a JAX-RS runtime or must be annotated with @Provider annotation to be automatically discovered by the JAX-RS runtime during a provider scanning phase.

@Consumes 注释与作者对 @Produces 的处理相同,只是相反。相同的匹配算法。还有 @Provider 注释,同样的处理。例如

@Provider
@Consumes(MediaType.APPLICATION_XML)
public class MyJAXBMessageBodyReader
implements MessageBodyReader<Customer> {
@Override
public boolean isReadable(Class<Customer> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {

return type == Customer.class
}
}

@POST
@Consumed(MediaType.APPLICATION_XML)
public Response createCustomer(Customer customer) {
customerService.save(customer);
return Response.created(newCustomerUri).build();
}

读取器将与我们的方法相匹配,并将输入流转换为 Customer 对象并将其传递给我们的方法。

就最后一个词“扫描阶段”而言,这只是 JAX_RS 实现扫描我们的包以查找要管理的组件。根据我们的配置(例如应该扫描哪些包),这种情况会在启动时发生

只是为了完整性......

MessageBodyWriter 有另一个方法getSize。如果我们不知道大小,我们可以返回-1,框架会为我们确定大小。

…为了更完整…

如果您想以编程方式注册 MessageBodyReaderMessageBodyWriter,请在 ClientClientBuilder(或任何 Configurable 实例)上使用 register 方法。

关于java - MessageBody写入器/读取器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26985183/

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