我正在尝试向媒体类型设置为multipart/form-data
的jaxrs服务执行请求。此请求包含实体列表(xml)和图像(png,二进制)。我已经按照BalusC的this线程中的描述创建了请求。
在wireshark中检查它之后,请求似乎没问题,除了ip头校验和错误。(说“可能是由IP校验和卸载引起的”。)
我的主要问题是如何在服务端处理多部分请求。我不希望包含来自apache.cxf,resteasy或任何类型的任何库。我想要依靠的是jaxrs api。
请求中的两个部分具有名称deliveries
和signature
,其中签名是以二进制形式发送的png图像文件。交付列表应该从xml解析(实体具有xmlrootelement
注释等,因此这部分单独工作)。我尝试用这种方式阅读不同的部分,但这真的是一个长期的目标;
@PUT
@Path("signOff")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void signOffDeliveries(@FormParam("deliveries") List<Delivery> deliveries, @FormParam("signature")File signature) {
//do something with the signature(image) and the list of deliveries.
}
这当然不起作用,如果我在Websphere上运行请求,它会给我一个404 http状态代码,当我向嵌入式openejb(在我们的集成测试框架中)运行请求时,它会给我一个415。如果我删除了FormParam
注释,请求会成功。
如何仅使用jaxrs api读取多部分请求的不同部分?
修改
好的,我将PUT
标记为POST
,并在参数中添加了@Encoding
注释:
@POST
@Path("signOff")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void signOffDeliveries(
@Encoded @FormParam("deliveries") String deliveries,
@Encoded @FormParam("signature") File signature) {
}
现在我将xml作为文本字符串,但即使有效负载的这一部分的Content-Type
设置为application/xml
,我也无法将其自动解组为交付列表。另一个问题是我收到的文件长度== 0,我无法从中读取任何字节。
我在这里错过了一个重点吗?
答案 0 :(得分:8)
事实上,我发现很难理解为什么JAX-RS规范没有标准化对此的支持(我刚刚创建了https://java.net/jira/browse/JAX_RS_SPEC-413来解决这个问题。)
然而,可以以独立于实现的方式支持多部分表单。您可以为MultiPart表单编写自己的MessageBodyReader,也可以使用像Apache Clerezza jaxrs.utils这样的库,它们提供了一个MultiPartBody对象,它们分别是MessageBodyReader。该库没有实现规范依赖性,因此您的应用程序将在任何jax-rs实现上运行。
有关如何使用Clerezza jaxrs.utils的示例,请参阅http://svn.apache.org/viewvc/stanbol/trunk/development/archetypes/stateless-webmodule/src/main/resources/archetype-resources/src/main/java/MultiEnhancer.java?revision=1465777&view=markup中的第105行。如果您不使用OSGi(使用白板注册资源),则必须将org.apache.clerezza.jaxrs.utils.form.MultiPartFormMessageBodyReader添加到您的应用程序。
答案 1 :(得分:1)
我已经在Glassfish 4中实现了这一点而没有与Jersey结合。 @See this post for details
答案 2 :(得分:-1)
我不希望包含来自apache.cxf,resteasy或任何类型的任何库。我想要依赖的是jaxrs api
您不能“依赖”API,因为它只包含接口。实现该接口的类来自RESTeasy,Jersey或CXF。
当我向嵌入式openejb运行请求时和415;
415表示“不支持方法”,当您向PUT期望的资源发送GET请求时会发生这种情况。
在这种情况下,我建议使用POST而不是PUT。我怀疑@FormParam
不适合在您的特定情况下使用PUT。