【问题标题】:Jersey 2.14: how to receive and parse multipart mime using custom MessageBodyReaderJersey 2.14:如何使用自定义 MessageBodyReader 接收和解析多部分 mime
【发布时间】:2014-12-24 08:04:49
【问题描述】:

我通常不习惯用 Java 编程,这是我的第一篇文章,所以我请求一点耐心。我无法将各个部分组合在一起,用于独立客户端,该客户端将通过 GET 请求然后从服务器接收多部分消息。请注意,我无法更改这些消息的格式。

收到的协议头看起来像这样:

HTTP/1.1 200 OK
Content-type: multipart/custom; boundary=custom-17940605525230162027
X-Custom-Domain-Name: my-custom-domain
Server: Myserver
Content-Length: 71576
Connection: Keep-Alive
Keep-Alive: timeout=5

接收到的正文具有上述自定义边界元素,格式如下(内容大多省略):

--custom-17940605525230162027
X-Custom-Designation: ack
Content-Type: application/xml
Content-Length: 291

<cust:ack>
A bunch of xml...
</cust:ack>

--custom-17940605525230162027
X-Custom-Designation: update
Content-Type: application/xml
Content-Length: 1101

<cust:update>
A bunch more xml...
</cust:update>

--custom-17940605525230162027
X-Custom-Designation: document
Content-Type: application/xml
Content-Length: 6259

<?xml version="1.0" encoding="UTF-8"?>
Lots more xml...

--custom-17940605525230162027
...

以下代码将正确地从服务器抓取上述内容(请暂时忽略无关的库):

package com.mycompany.multipart.test;

import java.io.IOException;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;


public class ClientMultipartTest {

    public static void main(String[] args) {

        Client client = ClientBuilder.newClient();
        HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("user1", "password1");
        WebTarget webTarget = client.target("http://theserver:80/test.xqy")
                .queryParam("domain", "12345")
                .queryParam("target", "67890");
        webTarget.register(feature);
        Invocation.Builder invocationBuilder = webTarget.request("multipart/mixed");
        Response response = invocationBuilder.get();
        System.out.println(response.getStatus());
        System.out.println(response.readEntity(String.class));      
    }
}

但我不太清楚如何将实体作为多部分对象实际提取出来。当我尝试以下代码时(从webTarget.register() 开始):

MultiPart response = webTarget.request("multipart/mixed").get(MultiPart.class);

我得到以下异常:

Dec 22, 2014 10:56:15 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom
SEVERE: MessageBodyReader not found for media type=multipart/custom; boundary=custom-17940605525230162027, type=class org.glassfish.jersey.media.multipart.MultiPart, genericType=class org.glassfish.jersey.media.multipart.MultiPart.
Exception in thread "main" org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=multipart/custom; boundary=custom-17940605525230162027, type=class org.glassfish.jersey.media.multipart.MultiPart, genericType=class org.glassfish.jersey.media.multipart.MultiPart.
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:225)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:761)
    at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90)
    at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)
    at com.mycompany.multipart.test.ClientMultipartTest.main(ClientMultipartTest.java:29)

我想我明白我需要创建和“注册”一个实现自定义 MessageBodyReader 接口的类(如 here 所示)。然而,这个例子让我感到困惑。

有人能指导我,让我能够得到一个可以解析其身体部位的 MultiPart 对象吗?我最终还需要能够构建一个仅包含 &lt;cust:ack&gt; 元素的多部分响应并将其发布回服务器。

非常感谢您提供的任何帮助!

【问题讨论】:

  • @peeskillet 我在上面的代码中没有这样做,我很确定一旦我克服了这个异常,我就需要这样做。但我也很确定这不是导致此异常的原因。
  • 我已经注册了 MultiPartFeature 并且仍然得到同样的异常。我什至尝试实现我自己的 @consumes multipart/custom 的 MessageBodyReader 类,但仍然得到相同的异常。我完全被难住了。

标签: java multipart jersey-2.0 jersey-client


【解决方案1】:

迟到比以往任何时候都好。您正在寻找的是:

MultiPart content = response.readEntity(MultiPart.class);

这将导致 Jersey 框架解析出内容并为您提供一个 MultiPart 对象,您可以通过该对象迭代各个部分。

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 1970-01-01
    • 2017-12-17
    • 2011-11-10
    • 1970-01-01
    • 2015-02-26
    • 2011-06-12
    • 1970-01-01
    • 2016-10-05
    相关资源
    最近更新 更多