2015-06-02 32 views
8

我正在編寫一個使用Jersey 並啓用了JacksonFeature的REST客戶端,這個web服務迫使我指定他們的自定義內容類型,即使它只是普通的JSON。換句話說,當我這樣做:Jersey REST客戶端 - 將自定義MediaType當作MediaType.APPLICATION_JSON

Request request = buildMySampleRequestPojo(); 

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

服務抱怨說我使用的是無效的內容類型。

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

然而,當我這樣做,我得到:我可以代替MediaType.APPLICATION_JSON常數指定其自定義命名的媒體類型解決這個

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

是否有辦法我可以讓Jersey將這個自定義的媒體類型名稱視爲常規JSON,而無需編寫自定義的MessageBodyWriter?

+0

您是否嘗試過使用傳統媒體類型格式'應用/ vnd.stupidNameThatReallyIsJustJSON + json'? –

+0

是的,在我的第二個代碼示例中,更多的是什麼格式o實際媒體類型名稱看起來像我只是試圖混淆它一點點 – kwikness

回答

7

我認爲你可以同時使用this (JAX-RS entity providers)this (use Jackson with Jersey),以達到你想要的。簡而言之,註冊一個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; 
    } 

} 

線的東西顯然,這只是一個起點,而不是一個工作的例子,但它應該給你足夠的信息來啓動。另外請記住,您必須將課程註冊到澤西島才能讓它使用它。

+0

還沒有忘記你的法郎,只是等待一些空閒時間來,所以我可以嘗試此解決方案。 – kwikness

+0

法郎你能提供一些更多的細節?在這種情況下我可以使用什麼MessageBodyWriter?我需要創建自己的班級嗎?是否有一個現有的「JSONMessageBodyWriter」類,我可以繼承子類,只需使用您提及的@Produces註釋進行註釋? – kwikness

+1

@kwikness'JacksonJsonProvider' –