Spring启动:使用ControllerAdvice for REST处理自定义异常

时间:2017-01-17 17:48:10

标签: java spring spring-boot spring-data-rest

我想使用@ControllerAdvice在一个地方处理所有异常。我编写了通用的异常处理程序类,它是:

// page 1
<form action="/testpage" method="POST" id="myForm">
    <input type="hidden" name="old_data" id="old_data">
</form>

<script>

.done(function (data) {
    console.log("done");

    $('#old_data').val(data);
    $('#myForm').submit();
})

</script>

// testpage
if(isset($_POST['old_data'])) {
    echo '<div id="testdiv">'.$_POST['old_data'].'</div>';
}

此异常处理程序适用于DB操作引发的异常:DataIntegrityViolationException但不适用于我的自定义异常:InconsistentEditException:

@ControllerAdvice(basePackageClasses = RepositoryRestExceptionHandler.class)
public class GenericRepositoryRestExceptionHandler{

    @Autowired
    MessageSource messageSource;

    @ExceptionHandler
    ResponseEntity<?> handleConflict(DataIntegrityViolationException e) {
        return response(HttpStatus.CONFLICT, 40901, "Operation cannot be performed. Integrity Constraint violated", e.getRootCause().getMessage(), "");
    }

    @ExceptionHandler(InconsistentEditException.class)
    ResponseEntity<?> handleInconsistentEditException(InconsistentEditException e){
        return response(HttpStatus.CONFLICT, 40902, e.getMessage());
    }

    private ResponseEntity<RestError> response(HttpStatus status, int code, String msg) {
        return response(status, code, msg, "", "");
    }

    private ResponseEntity<RestError> response(HttpStatus status, int code, String msg, String devMsg, String moreInfo) {
        return new ResponseEntity<>(new RestError(status.value(), code, msg, devMsg, moreInfo), status);
    }
}

它为我的自定义异常返回此响应:

public class InconsistentEditException extends RuntimeException{

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

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

我期待这样的回应:

{
    "timestamp":1484673344950,
    "status":500,
    "error":"Internal Server Error",
    "exception":"com.example.vmi.exception.InconsistentEditException",
    "message":"Operation restricted to prevent data Inconsistency.",
    "path":"/api/fits/2"
}

我不知道为什么异常处理程序不处理自定义异常。我错过了什么?

编辑:添加引发自定义异常的类。

{
    "status":409,
    "code":40902,
    "message":"Operation restricted to prevent data Inconsistency.",
    "devMessage":"",
    "moreInfo":""
}

stacktracke of log:

@Service
@Transactional(readOnly = true)
public class FitService {
    private final Logger logger = LoggerFactory.getLogger(BuyerService.class);

    @Autowired FitRepository fitRepository;

    @Autowired SKURepository skuRepository;

    public Fit findOne(Integer id) {
        return fitRepository.findOne(id);
    }

    public Fit findOne(String name) {
        return fitRepository.findByName(name);
    }
    @Transactional
    public Fit updateFit(Fit fit){

        System.out.println("No. of Skus: " + skuRepository.countByFit(fit));
        if (skuRepository.countByFit(fit) > 0){
            throw new InconsistentEditException("Operation restricted to prevent data Inconsistency.");
        }
        Fit fit2 = fitRepository.findOne(fit.getId());
        fit2.setName(fit.getName());
        return fit2;
    }

}

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您缺少一个注释:

@EnableWebMvc
@ControllerAdvice
public class GenericRepositoryRestExceptionHandler{

    @Autowired
    MessageSource messageSource;

    @ResponseBody
    @ExceptionHandler
    ResponseEntity<?> handleConflict(DataIntegrityViolationException e) {
        return response(HttpStatus.CONFLICT, 40901, "Operation cannot be performed. Integrity Constraint violated", e.getRootCause().getMessage(), "");
    }

    @ResponseBody
    @ExceptionHandler(InconsistentEditException.class)
    ResponseEntity<?> handleInconsistentEditException(InconsistentEditException e){
        return response(HttpStatus.CONFLICT, 40902, e.getMessage());
    }

    private ResponseEntity<RestError> response(HttpStatus status, int code, String msg) {
        return response(status, code, msg, "", "");
    }

    private ResponseEntity<RestError> response(HttpStatus status, int code, String msg, String devMsg, String moreInfo) {
        return new ResponseEntity<>(new RestError(status.value(), code, msg, devMsg, moreInfo), status);
    }
}

是您正在寻找的。

删除basePackages解决了问题。