Должна ли реализация @Provider MessageBodyReader <T>автоматически вызываться в JAX-RS на основе типа MIME в заголовке? - PullRequest
0 голосов
/ 19 апреля 2019

Я читал несколько уроков о jax-rs, микросервисах и буферах протоколов, но я не понимаю, как мне реализовать поддержку как буферов протоколов, так и json в моем проекте.

У меня оченьпроект, аналогичный описанному ниже в руководстве:

https://nobuco.wordpress.com/2011/03/28/support-both-protobuf-and-json-with-jersey-restful-web-service/

Функциональность, которой я не могу достичь, описана в ссылке как: «Джерси подберет правильного читателя /писатель, основанный на входящем типе контеста и принимающих заголовках. "

В моем случае этого практически не происходит.Установленный заголовок не влияет на то, какая функция вызывается.Что еще хуже, я могу тестировать только protobuf из java, поскольку Postman не поддерживает «application / x-protobuf».

Итак, я пытаюсь сделать следующее:

            ResteasyProviderFactory instance = ResteasyProviderFactory.getInstance();
            ResteasyClient client = new ResteasyClientBuilder().providerFactory(instance).build();
            ResteasyWebTarget target = client.target(backendAddress);
            target.request().header(HttpHeaders.ACCEPT, "application/x-protobuf");
            // Get a typed interface:
            IHelloBackend backend = target.proxy(IHelloBackend.class);
            HelloRequest.Builder requestBuilder = HelloRequest.newBuilder().setName(name);
            HelloRequest request = requestBuilder.build();
            HelloResponse response = backend.sayHello(headers, request);

Заголовок target.request (). (HttpHeaders.ACCEPT, "application / x-protobuf"); должен обеспечивать автоматическое переключение между двумя провайдерами, но это не так.Не могли бы вы помочь мне, как я мог бы вызвать этот автоматический провайдер на основе заголовка?

Пожалуйста, посмотрите классы моего провайдера, как показано ниже: Protobuf:

package providers;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;

import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import com.google.protobuf.Message;

@Provider
@Consumes("application/x-protobuf")
@Produces("application/x-protobuf")
public class ProtoBufProvider implements MessageBodyReader<Message>, MessageBodyWriter<Message> {
    @Override
    public boolean isReadable(Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return true;
    }

    @Override
    public Message readFrom(Class cls, Type type, Annotation[] annots, MediaType mediaType, MultivaluedMap map,
            InputStream stream) throws IOException, WebApplicationException {
        try {
            Method parseFromMethod = cls.getMethod("parseFrom", InputStream.class);
            System.out.println("received message Protobuf:");
            return (Message) parseFromMethod.invoke(null, stream);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public long getSize(Message message, Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return -1;
    }

    @Override
    public boolean isWriteable(Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return true;
    }

    @Override
    public void writeTo(Message message, Class cls, Type type, Annotation[] annots, MediaType mediaType,
            MultivaluedMap map, OutputStream stream) throws IOException, WebApplicationException {
        message.writeTo(stream);
    }
}

Json:

package providers;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import com.google.protobuf.Message;

@Provider
@Consumes("application/x-protobuf")
@Produces("application/json")
public class JsonProvider implements MessageBodyReader<Message>, MessageBodyWriter<Message> {
    @Override
    public boolean isReadable(Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return true;
    }

    @Override
    public Message readFrom(Class cls, Type type, Annotation[] annots, MediaType mediaType, MultivaluedMap map,
            InputStream stream) throws IOException, WebApplicationException {
        try {
            Method parseFromMethod = cls.getMethod("parseFrom", InputStream.class);
            System.out.println("received message JSON:");
            return (Message) parseFromMethod.invoke(null, stream);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public long getSize(Message message, Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return -1;
    }

    @Override
    public boolean isWriteable(Class cls, Type type, Annotation[] annots, MediaType mediaType) {
        return true;
    }

    @Override
    public void writeTo(Message message, Class cls, Type type, Annotation[] annots, MediaType mediaType,
            MultivaluedMap map, OutputStream stream) throws IOException, WebApplicationException {
        message.writeTo(stream);
    }
}
...