users@jersey.java.net

Re: [Jersey] Returning response in JSON format in case of Exceptions

From: Jonathan Hodges <hodgesz_at_gmail.com>
Date: Sat, 1 May 2010 09:37:25 -0600

Hello,

I am not sure if my issue is exactly the same as yours but it sounds similar
so I figured I would pose my question in this thread instead of creating a
new one. I also would like to return JSON or XML in the event of an
exception. Consider the following scenario.

Here is my server side resource method. Notice the MediaTypes that it
consumes as well as produces.


@PUT
@Path("/saveUserActivity")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_PLAIN})
public String saveUserActivity(UserActivityListJAXB userActivityListJAXB)
throws ValidationException, Exception {

...
...
}


Here is my ExceptionMapper.


@Provider
public class UserActivityRestValidationExceptionMapper implements
ExceptionMapper<ValidationException> {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Context
HttpHeaders hh;
 public Response toResponse(ValidationException e) {
logger.debug("ValidationException mapper: "+e.getClass().getName());

ErrorList errorList = new ErrorList();
Set<Error>errorSet = new HashSet<Error>();
Error error = new Error();
error.setCode(e.getValidationCode());
error.setMessage(e.getMessage());
errorSet.add(error);
 if (e.getValidationExceptions() != null &&
e.getValidationExceptions().size() > 0) {
 for (ValidationException ve : e.getValidationExceptions()) {
error = new Error();
error.setCode(ve.getValidationCode());
error.setMessage(ve.getMessage());
errorSet.add(error);
}
}
errorList.setError(errorSet);
 ResponseBuilder r = Response.status(Response.Status.BAD_REQUEST);
r.type(hh.getAcceptableMediaTypes().get(0));
//r.type(MediaType.APPLICATION_XML);
 r.entity(errorList);
 return r.build();
}
}


Here is my test class


@Test
public void saveUserSocialIdentityTest() {
UserSocialIdentityListJAXB userSocialIdentityListJAXB = new
UserSocialIdentityListJAXB();

...
...

String response =
wr.path("saveUserSocialIdentity")
.type(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.TEXT_PLAIN)
.header("Version", "1.0")
.put(String.class, userSocialIdentityListJAXB);
 assertTrue("Method: saveUserSocialIdentityTest \nMessage: Something wrong,
the returned " +
                "response is not 'OK'", response.equals("OK"));
}


In the event a ValidationException is thrown the
UserActivityRestValidationExceptionMapper.toResponse method is correctly
invoked. However when attempting to return the JSON or XML I get the
following error.

May 1, 2010 9:01:10 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class
com.ge.nbc.common.error.jaxb.ErrorL
ist, and Java type class com.ge.nbc.common.error.jaxb.ErrorList, and MIME
media
type text/plain was not found

In the mapper I attempt to set the Response to the correct MIME type with
the following code to no avail.

ResponseBuilder r = Response.status(Response.Status.BAD_REQUEST);
r.type(hh.getAcceptableMediaTypes().get(0));
r.entity(errorList);
return r.build();

The frustrating this is this was working earlier this week. I have been
pulling my hair out to figure out what I might have changed to make it fail.
 I am using the version 1.2-SNAPSHOT because it has a fix for including
entities in PUT and DELETE methods. Is it possible something might have
changed recently that would affect this?

Is this the correct approach to deal with this exception use case? I
realize that I might not be following best practices with the method
declaring a return MIME type of ‘text/plain’ but in exception cases return
‘application/json’ or ‘application/xml.’ Is this causing the issue by
chance?

Thanks in advance for your help.

-Jonathan



On Fri, Apr 30, 2010 at 8:12 AM, j2eeuser32 <nagmidde_at_gmail.com> wrote:

>
> Hi
>
> I am trying to figure out how to return response in JSON format in the case
> of exceptions. I have mapped the exception using ExceptionMapper, but the
> overridden toResponse method only returns Response object.
>
> Here is my code. Any help/ideas would be greatly appreciated.
>
> Thanks
>
> <code>
> @Path("/test")
> public class TestResource {
> @GET
> @Path("/userinfo")
> @Produces(MediaType.APPLICATION_JSON)
> public String getUserInfo(@QueryParam("userId") String userId) {
> .....
> throw new TestException("User not available");
> }
> }
>
> @Provider
> public class TestExceptionMapper implements ExceptionMapper<TestException>
> {
> public Response toResponse(TestException ex) {
> return
>
> Response.status(404).entity(ex.getMessage()).type("application/json").build();
> }
> }
> </code>
> --
> View this message in context:
> http://jersey.576304.n2.nabble.com/Returning-response-in-JSON-format-in-case-of-Exceptions-tp4985840p4985840.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>