Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Better Exception Handling in RESTful Java

DZone's Guide to

Better Exception Handling in RESTful Java

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

"Less time on exception handling at development, hard time on debugging in production"

Whenever we start learning a new programming language or concepts, it is better to understand how to handle the extreme cases or exceptions.

In this article, we are going to see how we can handle exceptions when we write RESTful web services using Java language. There are 3 main parts involved in the process.

    Exception wrapper
    Exception mapper
    Response marshaller
We will see each one of them in details...

Exception wrapper:

First we have to write a exception wrapper of our business exception. Something like an extended implementation of Java exception. This is an exception which we will throw from our business logic.

 public class CustomException extends Exception implements Serializable {

  private static final long serialVersionUID = -2018114370574835493L;
  public CustomException() {
    super();
  }

  public CustomException(String message) {
    super(message);
  }

  public CustomException(String message, Exception ex) {
    super(message, ex);
  }
}

Exception mapper:

Next we have to write a provider class for the above mentioned custom exception. This one is called as exception mapper. It will generate the desired response from our custom exception object at run-time.

 @Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {

 @Override
 public Response toResponse(CustomException ex) {
  CustomResponse CustomResponse = new CustomResponse(Response.Status.EXPECTATION_FAILED.getStatusCode());
  CustomResponse.setMessage(ex.getMessage());

  StringWriter writer = new StringWriter();
  ex.printStackTrace(new PrintWriter(writer));
  CustomResponse.setDetail(writer.toString());

  return Response.status(Response.Status.OK.getStatusCode())
    .entity(CustomResponse)
    .type(MediaType.APPLICATION_JSON)
    .build();
 }
}

Response marshaller:

Marshaling is the process of creating JSON / XML data from the given object. In our case we are going to create JSON response from the given Custom Response object. Custom Response object is the holder for the response which will be transferred as a JSON data. Marshalling Java to JSON is covered in details. Please refer if you need more information.

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomResponseMarshaller implements MessageBodyWriter<CustomResponse> {

 @Override
 public long getSize(CustomResponse CustomResponse, Class<?> clazz,
   Type type, Annotation[] annotations, MediaType mediaType) {
  return -1;
 }

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

 @Override
 public void writeTo(CustomResponse CustomResponse, Class<?> clazz,
   Type type, Annotation[] annotations, MediaType mediaType,
   MultivaluedMap<String, Object> valueMap, OutputStream stream) throws IOException, WebApplicationException {

  JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
  jsonObjectBuilder.add("status", CustomResponse.getStatus());

  jsonObjectBuilder.add("data", (CustomResponse.getData() != null) ? CustomResponse.getData() : "");
  jsonObjectBuilder.add("message", (CustomResponse.getMessage() != null) ? CustomResponse.getMessage() : "");
  jsonObjectBuilder.add("detail", (CustomResponse.getDetail() != null) ? CustomResponse.getDetail() : "");

  DataOutputStream outputStream = new DataOutputStream(stream);
  outputStream.writeBytes(jsonObjectBuilder.build().toString());
 }
}


Finally we can throw our custom exception from the resource method like the below. The Custom exception will be handled based on the provider (mapper) available above in the code.

 @Path("hello")
public class CustomRequestResource {

 @POST
 @Produces(MediaType.APPLICATION_JSON)
 public Response request(@FormParam("name") String name,
   @FormParam("email") String email,
   @FormParam("message") String message) throws CustomException {

  if (name == null || email == null || message == null) {
      throw new CustomException("Please fill name, email and message");
    }

  return Response.status(CustomResponse.getStatus())
    .entity(CustomResponse)
    .type(MediaType.APPLICATION_JSON)
    .build();
 }
}

I hope you have enjoyed with this article. Share your comments and feedback if you have any...


Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
java ,rest

Published at DZone with permission of Thamizh Arasu, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}