【问题标题】:RESTEasy doesn't recognize custom message body writerRESTEasy 无法识别自定义消息正文编写器
【发布时间】:2013-07-11 12:31:06
【问题描述】:

我的 MessageBodyWriter

@Provider
@Produces("text/csv")
public class CSVMessageBodyWriter implements MessageBodyWriter<JaxbList>

    public static final String CONTENT_DISPOSITION_HEADER = "Content-Disposition";     
   //$NON-NLS-1$
    private final static HeaderDelegate<ContentDispositionHeader> header = RuntimeDelegate.getInstance().createHeaderDelegate(ContentDispositionHeader.class);

    public long getSize(JaxbList t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

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

    public void writeTo(JaxbList t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
                    OutputStream entityStream) throws IOException, WebApplicationException {

        // set content disposition. This will enable browsers to open excel
        ContentDispositionHeader contentDispositionHeader = ContentDispositionHeader.createContentDispositionHeader(MediaTypeUtils.CSV_TYPE);
        contentDispositionHeader.setFileName("representation"); //$NON-NLS-1$
        httpHeaders.putSingle(CONTENT_DISPOSITION_HEADER, header.toString(contentDispositionHeader));

        Charset charset = Charset.forName(ProviderUtils.getCharset(mediaType));
        OutputStreamWriter writer = new OutputStreamWriter(entityStream, charset);

        PrintWriter printWriter = new PrintWriter(writer);
        Iterator<String[]> rows = ((CsvSerializer) t).getEntities();
        while (rows.hasNext()) {
            printWriter.println(CsvWriter.getCSVRow(rows.next()));
        }
        printWriter.flush();
    }
}

我的 REST 应用程序

@Path("app/v3")
@GZIP
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, "text/csv"})
 public class ApplicationREST

应用扩展

@ApplicationPath("/")
public class JaxRsActivator extends Application {

  private Set<Object> singletons = new HashSet<Object>();
  private Set<Class<?>> classes = new HashSet<Class<?>>();

  public JaxRsActivator() {
    singletons.add(new CSVMessageBodyWriter());
    classes.add(ApplicationREST.class);
  }

  @Override
  public Set<Object> getSingletons() {
    Set<Object> defaults = super.getSingletons();
    singletons.addAll(defaults);
    return singletons;
  }

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

当我在调试模式下运行时,我可以点击我的 JaxRsActivator 类,所以我知道提供程序正在加载。但是我收到错误“找不到类型的响应对象的 MessageBodyWriter:net.comp.jaxb.JaxbList of media type: text/csv”

【问题讨论】:

  • classes.add(AppREST.class); 是错字吗?还是您只是忘记以某种方式使 ApplicationREST 可用?
  • 这是一个错字。它的ApplicationREST
  • @Cam Sonaris - 你能发布你的 MessageBodyWriter 实现吗?
  • @GregWhitaker 进行了编辑,但是我不确定这有什么帮助,因为它甚至没有影响到课堂
  • @Cam Sonaris - 您是否尝试将类添加到 web.xml 中的 resteasy.providers 上下文参数?

标签: java jax-rs resteasy


【解决方案1】:

根据您上面的代码,您的CSVMessageBodyWriter 似乎正在被调用,但您的isWriteable 检查失败。

您的isWriteable 支票总是会返回假。您正在检查 JaxbList 是否可以从 CSVSerializer 分配。这总是会失败,您的CSVMessageBodyWriter 将无法处理text/csv

尝试将您的 isWriteable 方法更改为以下内容:

public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) 
{
    return true;
}

这将序列化所有text/csv 注释的方法。如果您想将其限制为JaxbList,那么您可以执行以下操作:

public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) 
{
    ParameterizedType paramType = (ParameterizedType) genericType;

    if(paramType.getRawType().equals(JaxbList.class))
    {
        return true;
    }

    return false;
}

这是一个配置自定义MessageBodyWriter 的简单工作示例:

应用程序

public class ProductGuideApplication extends Application
{
    private Set<Object> singletons = new HashSet<Object>();
    private Set<Class<?>> classes = new HashSet<Class<?>>();

    public ProductGuideApplication() 
    { 
        singletons.add(new CSVMessageBodyWriter());
        classes.add(FooResource.class);
    }

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

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

资源

@Path("/foo")
public class FooResource
{
    @GET
    @Produces("text/csv")
    public List<Consumer> getConsumers()
    {
        Consumer consumer1 = new Consumer();
        consumer1.setId("1234");
        consumer1.setGender("Male");

        Consumer consumer2 = new Consumer();
        consumer2.setId("2345");
        consumer2.setGender("Male");

        List<Consumer> consumers = new ArrayList<Consumer>();
        consumers.add(consumer1);
        consumers.add(consumer2);

        return consumers;
    }
}

MessageBodyWriter

@Provider
@Produces("text/csv")
public class CSVMessageBodyWriter implements MessageBodyWriter<List<Consumer>>
{
    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) 
    {
        ParameterizedType paramType = (ParameterizedType) genericType;

        if(paramType.getRawType().equals(List.class))
        {
            if(paramType.getActualTypeArguments()[0].equals(Consumer.class))
            {
                return true;
            }
        }

        return false;
    }

    @Override
    public long getSize(List<Consumer> t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) 
    {
        return 0;
    }

    @Override
    public void writeTo(List<Consumer> t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException 
    {
        //Write your CSV to entityStream here.
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2016-01-30
    相关资源
    最近更新 更多