2011-11-16 69 views
1

我該如何告訴RESTEasy(一個jax-rs實現),「嘿,當你被問到IFoo時,請繼續做一個Foo對象?接口的自定義jax-rs實體提供程序?

我現在的(錯誤)試圖

我有,我想消耗ReportPieceDAO對象的API接入點。 ReportPieceDAO有作爲List<StandardScoreReport>的成員。 StandardScoreReport是一個接口,由StandardScoreReportImpl實現。

@Path("pieces") 
@PUT 
@Produces("application/json") 
@Consumes("application/json") 
public Iterable<Long> putReportPiece(List<ReportPieceDAO> reportPieces) { 
    return getDataCoordinator().updateReportPieces(getAuthenticatedUser(), reportPieces); 
} 

在我加入List<StandardScoreReport>成員之前,此入口點工作良好。由於StandardScoreReport是一個抽象接口,因此RESTEasy不能自動構造一個接口 - 它抱怨StandardScoreReport沒有默認構造函數。

所以,我想使某種適配器或供應商,在案件建造的StandardScoreReportImpl是在需要可StandardScoreReport

@Provider 
@Consumes("application/json") 
public class StandardScoreReportProvider implements MessageBodyReader<StandardScoreReport>{ 

    @Override 
    public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, 
      MediaType arg3) { 
     return true; 
    } 

    @Override 
    public StandardScoreReport readFrom(Class<StandardScoreReport> arg0, 
      Type arg1, Annotation[] arg2, MediaType arg3, 
      MultivaluedMap<String, String> arg4, InputStream arg5) 
      throws IOException, WebApplicationException { 

      //I'm hoping I can just call some "default" code that 
      //would run if StandardScoreReportImpl were naturally 
      //encountered, and not have to write my own unmarshalling code. 

     return new StandardScoreReportImpl(); 
    } 

} 

但沒有這個代碼是永遠執行。這是我的應用程序說明:

public class RESTEasyApplicationDescription extends Application 
{ 
    HashSet<Class<?>> classes = new HashSet<Class<?>>(); 

    public RESTEasyApplicationDescription() 
    { 
     classes.add(APIRoot.class); 
     classes.add(ReportsRoot.class); 
     classes.add(StandardScoreReportProvider.class); 
     classes.add(StandardScoreReport.class); 
     classes.add(ReportPiece.class); 
    } 

    @Override 
    public Set<Class<?>> getClasses() { 
     return classes; 
    } 

    @Override 
    public Set<Object> getSingletons() { 
     return null; 
    } 
} 

回答

2

提供者在將應用程序部署到服務器時進行註冊。服務器自動知道句柄如何接收/傳遞某個對象。 您必須創建具有@Provider,然後如果你

創建一個從POST Java對象,你可以使用一個類:@Consumes
從Web服務發送一個Java對象響應呼叫您可以使用:@Produces

並指定類型。
例子: 我,讓我一個PDF當我打電話,這是沒有消耗什麼,它只是給我一個PDF文件的服務:
MyService.java

@GET 
@Path("/report.{format}") 
@Produces({ MediaType.TEXT_HTML, "application/pdf" }) 
public Response recuperarReporte(){ 
    private ByteArrayOutputStream responseEntity = ....; 
    Response 
      .ok() 
      .entity(responseEntity) 
      .type("application/pdf").build(); 
} 

MyPDFProvider .java

@Produces("application/pdf") 
@Provider 
public class MyPDFProvider implements MessageBodyWriter<ByteArrayOutputStream> 
{ 

    @Override 
    public long getSize(ByteArrayOutputStream stream, Class<?> type, 
      Type genericType, Annotation[] annotations, MediaType mediaType) 
    { 
     return stream.size(); 
    } 

    @Override 
    public boolean isWriteable(Class<?> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType) 
    { 
     return ByteArrayOutputStream.class.isAssignableFrom(type); 
    } 

    @Override 
    public void writeTo(ByteArrayOutputStream t, Class<?> type, 
      Type genericType, Annotation[] annotations, MediaType mediaType, 
      MultivaluedMap<String, Object> httpHeaders, 
      OutputStream entityStream) throws IOException, 
      WebApplicationException 
    { 
     entityStream.write(t.toByteArray()); 
    } 
} 
+0

謝謝您的詳細解答!我只是更新了我的問題,以更具體地瞭解我的情況 - 我不需要一種方法將對象寫入輸出流,而是從輸入流中讀取特定對象的方式。我想將所有「StandardScoreReport」實例映射到默認的「StandardScoreReportImpl」解串器。 –

相關問題