Jersey 2.14: как да получавате и анализирате многочастна mime с помощта на персонализиран MessageBodyReader

Обикновено не съм свикнал да програмирам на 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> елементите и да го публикувам обратно на сървъра.

Много благодаря предварително за всяка помощ, която може да бъде оказана!


person Hallmarc    schedule 24.12.2014    source източник
comment
@peeskillet Не направих това в кода по-горе и съм почти сигурен, че ще трябва да го направя, след като премина това изключение. Но също така съм почти сигурен, че това не е причината за това изключение.   -  person Hallmarc    schedule 25.12.2014
comment
Регистрирах MultiPartFeature и все още получавам същото изключение. Дори се опитах да внедря свой собствен клас MessageBodyReader, който @consumes multipart/custom и все още получавам същото изключение. Напълно съм объркана.   -  person Hallmarc    schedule 29.12.2014


Отговори (1)


По-добре късно от всякога. Това, което търсите е това:

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

Това ще накара рамката Jersey да анализира съдържанието и да ви даде обект MultiPart, чрез който можете да обикаляте частите.

person Diego Rivera    schedule 02.10.2019