Обычно я не привык к программированию на 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 (как показано здесь). Однако этот пример сбивает меня с толку.
Сможет ли кто-нибудь направить меня, чтобы я мог получить объект MultiPart, части тела которого можно анализировать? Мне также в конечном итоге нужно иметь возможность создать составной ответ, состоящий только из элементов <cust:ack>
, и отправить его обратно на сервер.
Заранее большое спасибо за любую помощь, которая может быть оказана!