簡體   English   中英

Jersey REST客戶端 - 將自定義MediaType視為MediaType.APPLICATION_JSON

[英]Jersey REST Client - Treat Custom MediaType as MediaType.APPLICATION_JSON

我正在編寫一個REST客戶端,使用Jersey 和JacksonFeature啟用了一個Web服務,強制我指定他們的自定義內容類型,即使它只是普通的JSON。 換句話說,當我這樣做時:

Request request = buildMySampleRequestPojo();

Response response = requestBuilder.post(
        Entity.entity(request, MediaType.APPLICATION_JSON)
);

該服務抱怨我使用的內容類型無效。 我可以通過指定自定義命名的媒體類型來代替MediaType.APPLICATION_JSON常量來解決這個問題:

Response response = requestBuilder.post(
        Entity.entity(request, "vnd.stupidNameThatReallyIsJustJSON+json")
);

但是,當我這樣做時,我得到:

*SEVERE: MessageBodyWriter not found for media type=stupidNameThatReallyIsJustJSON*

有沒有一種方法可以讓Jersey對待這個自定義的媒體類型名稱,就好像它是普通的JSON而不編寫自定義的MessageBodyWriter?

我認為你可以使用這兩個(JAX-RS實體提供者)這個(使用傑克遜與澤西島) ,以實現你想要的。 簡而言之,注冊一個使用@Produces("application/vnd.stupidNameThatReallyIsJustJSON+json")注釋的MessageBodyWriter @Produces("application/vnd.stupidNameThatReallyIsJustJSON+json")並在實現中將編組/解組委托給Jackson。

編輯:嘗試一些類似的東西

package my.pack.age;

import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider;
import com.sun.jersey.core.util.ReaderWriter;

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

@Produces("application/vnd.stupidNameThatReallyIsJustJSON+json")
public class MyJsonBodyWriter<T> extends AbstractMessageReaderWriterProvider<T> {

    // T should be your pojo in this case. If you can make your pojo compatible with org.codehaus.jettison.json.JSONObject,
    // then you can extend com.sun.jersey.json.impl.provider.entity.JSONObjectProvider and delegate all the methods of
    // MessageBodyWriter (and MessageBodyReader) to that. Otherwise just implement them.

    @Override
    public T readFrom(Class<T> type, Type genericType, Annotation annotations[], MediaType mediaType,MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
        try {
//            deserialize entityStream according to the given media type and return a new instance of T.
//            
//            You can do it like this (just an example) :
//            JSONObject myObject = new JSONObject();
//            try {
//                these names and values should come from the stream.
//                myObject.put("name", "Agamemnon");
//                myObject.put("age", 32);
//            } catch (JSONException ex) {
//                LOGGER.log(Level.SEVERE, "Error ...", ex);
//            }
            return null;
        } catch (Exception e) {
            throw new WebApplicationException(new Exception("Error during deserialization", e),400);
        }
    }

        @Override
    public void writeTo(T t,Class<?> type, Type genericType, Annotation annotations[], MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
        try {
            OutputStreamWriter writer = new OutputStreamWriter(entityStream, ReaderWriter.getCharset(mediaType));
            // write t on the writer
            writer.flush();
        } catch (Exception e) {
            throw new WebApplicationException( new Exception("Error during serialization", e), 500);
        }
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // should return true if this class can serialize the given type to the given media type
        return true;
    }

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // should return true if this class can deserialize the given type to the given media type
        return true;
    }

    @Override
    public long getSize(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // calculate and return content-lenght, i.e. the lenght of the serialized representation of t
        return 0;
    }

}

顯然這只是一個起點,而不是一個工作的例子,但它應該給你足夠的信息來啟動。 還要記住,您必須將該類注冊到Jersey才能讓它使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM