Short version of the question:
Using Jersey, how can I determine the @Produces
type at runtime?
Long version of the question:
I wrote a REST call using jersy as follows:
@GET
@Path("/getVideo")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
public Response getAllVideos(@QueryParam("videoID") Long videoID) throws ApiException, SQLException {
--some code--
Response r ...;
return r;
}
If the user provides a valid videoID
then this should return an mp4
file, hence the @Produces({MediaType.APPLICATION_OCTET_STREAM,
. However, if an exception is thrown, such as a providing wrong videoID
I want to return a json
describing the exception.
The way it currently works is, that if a valid ID is provided, it returns a 200
with the mp4 file. But if an exception is thrown, it responds with a 500
and a message Could not find MessageBodyWriter for response object of type: com.my.package.Errors$CustomError of media type: application/octet-stream
.
Based on the Jersey documentation the response's return type is determined is by the accept
type of the request.
My problem is that I don't know in advance, when sending the request what type of response I want back (because I hope the request will be successful). Instead, I want to determine the response type at runtime based on whether or not an exception was thrown.
How can I do that?
(I think my question is similar to this question but I am not using Spring).
This will probably work because your exception says it couldn't find a message writer for CustomError
@Provider
@Produces(MediaType.APPLICATION_OCTET_STREAM) //I think you will have to leave this as octet_stream so jax-rs will pick as valid message writer
public class CustomErrorBodyWriter implements MessageBodyWriter<CustomError> {
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return type == CustomError.class;
}
@Override
public long getSize(CustomError customError, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
// deprecated by JAX-RS 2.0 and ignored by Jersey runtime
return 0;
}
@Override
public void writeTo(CustomError customError, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
OutputStream out) throws IOException, WebApplicationException {
//manipulate the httpHeaders to have content-type application/json
//transalate customError and write it to OutputStream
Writer writer = new PrintWriter(out);
writer.write("{ \"key\" : \"some random json to see if it works\" }");
writer.flush();
writer.close();
}
}