简体   繁体   中英

Handling and Mapping Runtime Exceptions in REST Resource to JAX-RS Response

I have a RESTful web application that connects to a database and has the normal REST, business logic service and persistence layers. What is the JAX-RS standard approach to handling Runtime errors, like database connection is not available, in a RESTful layer? I believe the approach I have below, where I wrap any call to my service/persistence layers with a try/catch for the Throwable and throw my custom MyAppRuntimeException is a bit awkward. Any suggestions?

RESTful Service:

@Path("service")
@Consumes({"application/json"})
@Produces({"application/json"})
public class MyResource {
  @GET
  @Path("/{id}")
  public Response getPage(@PathParam("id") long id){
    Object test=null;
    try {
         test = ...
      //call business logic service method here which makes a call to database and populates test instance
    } catch (Throwable e) {
      throw new MyAppRuntimeException("custom error message string");
    }

    if(test != null){
        return Response.ok(test).build();
    }else{
        return Response.status(Status.NOT_FOUND).build();
    }

  }
}

Custom Exception:

public class MyAppRuntimeException extends RuntimeException {
  private static final long serialVersionUID = 1L;


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

  public MyAppRuntimeException(String message, Throwable cause) {
    super(message, cause);
  }


} 

Exception JAX-RS Response Mapper:

@Provider
public class MyAppRuntimeExceptionMapper implements ExceptionMapper<MyAppRuntimeException> {

  private static final String ERROR_KEY = "DATA_ERROR";

  @Override
  public Response toResponse(MyAppRuntimeException exception) {

    ErrorMessage errorMessage = new ErrorMessage(ERROR_KEY, exception.getMessage(), null);
    return Response.status(Status.INTERNAL_SERVER_ERROR).entity(errorMessageDTO).build();
  }

}

Just have your exception class extend WebApplicationException and throw it wherever you like. You can see in the example below that you can customize the response in whatever way is necessary. Happy coding!

Note: this example handles 403 errors, but you can easily create exceptions to handle 500 , 503 , etc.

package my.package.name;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.Serializable;

public class Http401NotAuthorizedException extends WebApplicationException implements Serializable {
  private static final long serialVersionUID = 1L;
  public Http401NotAuthorizedException(String msg){
    super(
      Response
        .status(Response.Status.FORBIDDEN)
        .header("Pragma", "no-cache, no-store")
        .header("Cache-Control", "no-cache, no-store")
        .header("Expires", "0")
        .entity(msg)
        .build()
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM