How to return http status code for exceptions in rest services

In my application I have different layers like the rest layer, service layer and DB layer, according to business scenarios I am trowing different business exceptions from the service layer.

But now, I have to set different HTTP codes like 400, 403, 409, 412.. to REST responses.

How can I set different HTTP status codes based on different scenarios?

Which is the most feasible way like: aspect, exception mapper, or ....?

Since I can set HTTP status only once in rest layer ( referred this ), I am not able to map to different HTTP codes because my exception is from service layer.

My exception class looks like this:

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

    public BusinessException(ErrorEnumeration error) {

    }
    public BusinessException(Exception e, ErrorEnumeration error) {

    }
}

and the exception will be thrown from the service like this:

 throw new BusinessException(ErrorEnumeration.VALIDATION_FAILED);

Please help by suggesting a solution


You can use exceptions defined in jax-rs or you can use your own exceptions. Fist catch your business exceptions and convert them to jax-rs versions. For example, for 404 you can throw javax.ws.rs.NotFoundException.

You can also write your own exceptions by extending them from javax.ws.rs.ClientErrorException

Here is an example for 409-Conflict status exception

import javax.ws.rs.ClientErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

public class ConflictException extends ClientErrorException{

    public ConflictException(Response.Status status) {
        super(Response.Status.CONFLICT); // 409
    }
}

Update

Most simple and feasible way is catching your business exceptions and re-throw them with jax-rs exceptions.

try{
  businessService.executeBusinessRule();
}catch (BusinessException e){
  // It is better if your BusinessException has some child class to handle
  if(e.getError() == ErrorEnumeration.VALIDATION_FAILED){
    throw new BadRequestException();
  }else{
    throw new ConflictException();
  }
}

If you are using spring you can always catch these exceptions using aop.

@Aspect
public class BusinessExceptionInterceptor{
@AfterThrowing(pointcut = "execution(* com.your.service.packge..* (..))", throwing = "e")
public void errorInterceptor(BusinessException e) {
   // re-throw again...
}

Update 2

Also it is better to define a new exception instead of reusing same exception with different state. You can define a new ValidationException which extends from BusinessException like this.

public class ValidationException extends BusinessException{

    public ValidationException() {
        super(ErrorEnumeration.VALIDATION_FAILED);
    }
}

By using this way you can still handle all the BusinessException but it is easier to identify or map them to Jax-rs exceptions.

链接地址: http://www.djcxy.com/p/45576.html

上一篇: 与泽西的ExceptionMapper页面

下一篇: 如何为休息服务中的异常返回http状态码