我有一个sdr项目,我在实体设置器中进行一些基本验证,如果模型无效则抛出域异常。我无法在异常中获取消息源,以便我可以本地化业务异常消息。我尝试过的自定义异常类是:
@ResponseStatus(org.springframework.http.HttpStatus.CONFLICT)
public class DoublePriceException extends Exception {
@Autowired
static ReloadableResourceBundleMessageSource messageSource;
private static final long serialVersionUID = 1L;
public DoublePriceException(OrderItem orderItem) {
super(String.format(
messageSource.getMessage("exception.doublePricedItem", null, LocaleContextHolder.getLocale()),
orderItem.name));
}
}
我如何尝试抛出这个mofo:
public void setPrices(List<Price> prices) throws DoublePriceException {
for (Price price : prices) {
List<Price> itemsPrices = prices.stream().filter(it -> price.item.equals(it.item)).collect(Collectors.toList());
if(itemsPrices.size() > 1)
throw new DoublePriceException(itemsPrices.get(0).item);
}
this.prices = prices;
}
messageSource始终为null。我正在尝试无法实现的目标吗?
答案 0 :(得分:1)
DoublePriceException
显然不是Spring托管Bean,因此不起作用。
您可以在应用程序中注册Spring ControllerAdvice
来处理异常并生成合适的响应。
/**
* Spring MVC @link {@link ControllerAdvice} which
* is applied to all Controllers and which will handle
* conversion of exceptions to an appropriate JSON response.
*/
@ControllerAdvice
public class ErrorHandlingAdvice
{
/**
* Handles a @DoublePriceException
*
* @param ex the DoublePriceException
*
* @return JSON String with the error details.
*/
@ExceptionHandler(DoublePriceException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Object processValidationError(DoublePriceException ex)
{
//return suitable representation of the error message
//e.g. return Collections.singletonMap("error", "my error message");
}
}
将上述内容放在Spring框架扫描的软件包中应该足以让它被检测和应用。
答案 1 :(得分:0)
我能想出的最好的方法就是抓住HttpMessageNotReadableException
并致电getMostSpecificCause()
,如下所示:
@RestControllerAdvice
public class ExceptionHandlingAdvice {
@Autowired
private MessageSource messageSource;
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<Object> onException(HttpMessageNotReadableException ex, WebRequest request) {
Locale locale = request.getLocale();
Throwable cause = ex.getMostSpecificCause();
String message = cause.getMessage();
if (cause instanceof MultiplePriceException) {
message = messageSource.getMessage("exception.multiple.price",
new Object[] { ((MultiplePriceException) cause).orderItem.name }, locale);
}
return new ResponseEntity(Collections.singletonMap("error", message), new HttpHeaders(),
HttpStatus.BAD_REQUEST);
}
}