如何使Spring Converter抛出自定义异常而不是ConversionFailedException?

时间:2018-01-30 15:22:41

标签: java spring spring-mvc spring-boot converter

我的代码库中有一堆自定义弹簧转换器,如:

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类中捕获特定的异常?

3 个答案:

答案 0 :(得分:1)

您需要实现将处理您的例外的类

@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&#34;带有(注释)的类可以显式声明为Spring bean,也可以通过类路径扫描自动检测&#34; show documentation
@ExceptionHandler定义了您想要捕获的异常 @ResponseStatus定义了http响应状态
@ResponseBody自动将响应序列化为json对象

对于我的项目,我定义了一个ErrorDTO来格式化响应,你也可以这样做,你只需构建你的对象并将其返回
您还可以将要执行的代码放入此方法中,并在需要时引发其他异常

答案 1 :(得分:0)

您可以编写一个包装Spring ConversionService的简单适配器类。在该类中,您将拥有一个convert()方法,该方法在try / catch中委托给包装的ConversionService方法,捕获ConversionFailedException,检查它(例如使用getRootCause())并重新抛出,作为您选择的例外。然后,对于否则将使用ConversionService的所有类,您将使用您的包装类。

答案 2 :(得分:0)

您违反了Single Responsibility Principle。验证转换后的对象不是不是。如果您能够成功进行转换,则应使用here中所述的方法之一分别进行验证。

例如,考虑将字符串转换为纬度。如果可以将字符串解析为双精度型,则转换器应该很满意。如果要验证double是否在[-90,+ 90]范围内,则应使用验证器而不是转换器。

在处理异常时(例如在@ControllerAdvice中说),不混淆不同的问题会很有帮助。