Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a MessageBodyWriter to return a custom object as HTML in RestEasy?

I'm using RestEasy together with Spring in Tomcat. I have a simple controller method which I want to use via Ajax (with JSON or XML response) and via a standard browser request (Using HTML as a response). It works when I use simple return data types like a string but I need to return a custom object:

@POST
@Path("fooBar")
public RequestResult fooBar()
{
    return new RequestResult();
}

This is the RequestResult object (Just a dummy implementation for demonstration):

@XmlRootElement(name = "result")
public final class RequestResult
{
    @XmlAttribute
    public boolean getWhatever()
    {
        return "whatever";
    }
}

It works when requesting it as JSON or XML but when requesting it as HTML I get the error message Could not find JAXBContextFinder for media type: text/html. It's clear that it can't work because RestEasy doesn't know how to convert this object to HTML. So I added this test MessageBodyWriter:

@Provider
@Produces("text/html")
public class ResultProvider implements MessageBodyWriter<RequestResult>
{
    @Override
    public boolean isWriteable(final Class<?> type, final Type genericType,
        final Annotation[] annotations, final MediaType mediaType)
    {
        return true;
    }

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

    @Override
    public void writeTo(final RequestResult t, final Class<?> type, final Type genericType,
        final Annotation[] annotations, final MediaType mediaType,
        final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
        throws IOException, WebApplicationException
    {
        final PrintWriter writer = new PrintWriter(entityStream);
        writer.println("Test");
    }
}

But this doesn't change anything. No method of this provider is ever called. I'm not sure if I have to register it somewhere. All other classes are found automatically by classpath scanning so I guess this also happens for providers.

I'm pretty sure I made something wrong or I forgot something. Any hints?

like image 653
kayahr Avatar asked Nov 05 '22 14:11

kayahr


1 Answers

Try adding adding a @Produces annotation that includes "text/html" to your fooBar() method (I included JSON and XML because it sounded like you wanted all three). When I did that, your ResultProvider was called. Let me know if that works for you!

@POST
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_HTML })
@Path("fooBar")
public RequestResult fooBar()
{
    return new RequestResult();
}
like image 195
bamana Avatar answered Nov 14 '22 22:11

bamana