我的代码库中有一堆自定义弹簧转换器,如:
public class ElasticSearchConverter implements Converter<RequestModel, ResponseModel> {
@Override
public final ResponseModel convert(RequestModel requestModel) {
if(!requestModel.isValid()) {
throw new ElasticSearchException("Request Model is not valid");
}
... Implement converter
}
}
我使用spring ConversionService从服务中调用这些转换器
@Service
public class ElasticService {
@Autowired
private ConversionService conversionService;
public ResponseModel getResponse(RequestModel requestModel) {
//Throws ConversionFailedException instead of ElasticSearchException
ResponseModel responseModel = conversionService.convert(requestModel, ResponseModel.class);
return responseModel;
}
}
我的问题是,当我把我的ElasticSearchException
扔进我的ElasticSearchConverter
里面时,它会被弹簧ConversionUtils
类中的一个并被转换为ConversionFailedException
。我想抓住我投入转换器的特定ElasticSearchException
。
如何从我的服务类中的spring Converter
类中捕获特定的异常?
您需要实现将处理您的异常的类
@ControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler(ConversionFailedException.class) //handle your Exception
@ResponseStatus(HttpStatus.BadRequest) // Define the status you want to return
@ResponseBody
public ErrorDTO processElasticSearchException(ConversionFailedException ex) {
return new ErrorDTO();
/* Format your response as you need*/
}
}
@ControllerAdvice
“具有(注释)的类可以显式声明为Spring bean或通过类路径扫描自动检测”show documentation
@ExceptionHandler
定义了您想要捕获的异常
@ResponseStatus
定义了http响应状态
@ResponseBody
将自动响应序列化为json对象
对于我的项目,我定义了一个ErrorDTO来格式化响应,你也可以这样做,你只需要构造你的对象并返回它 您还可以将要执行的代码放入此方法中,并在需要时引发其他异常
您可以编写一个包装Spring ConversionService的简单适配器类。在该类中,您将拥有一个convert()方法,该方法在try / catch中委托给包装的ConversionService方法,捕获ConversionFailedException,检查它(例如使用getRootCause())并重新抛出,作为您选择的例外。然后对于否则将使用ConversionService的所有类,您将使用您的包装类。
你违反了Single Responsibility Principle。验证转换后的对象不是转换器的工作。如果您能够成功完成转换,则应使用here描述的方法之一单独进行验证。
例如,考虑将字符串转换为纬度。如果字符串可以解析为double,转换器应该很高兴。如果要验证double是否在[-90,+ 90]范围内,则应该在验证器而不是转换器中执行此操作。
在@ControllerAdvice
中,当你处理异常时,不要混淆不同的关注点会有很大帮助。