在Spring MVC应用程序中,作为一种好的做法,Web配置应仅使用“前端”组件,例如@Controller
或@RestController
。
Root应用程序上下文应拾取所有其他bean。
我已经按照以下方式定义了Web配置(请记住,我不需要@EnableMvc
注释,因为它扩展了WebMvcConfigurationSupport
)
@Configuration
@ComponentScan(
basePackages = { ... },
useDefaultFilters = false,
includeFilters = @Filter({
Controller.class,
ControllerAdvice.class}))
和Root配置如下。
@Configuration
@ComponentScan(
basePackages = { ... },
excludeFilters = @Filter({
Controller.class,
ControllerAdvice.class}))
我定义了两个@RestControllerAdvice
类,第一个捕获所有通用的Exception
,第二个捕获更具体的ServiceException
。
抛出ServiceException
时,从不调用特定顾问,而是仅选择普通顾问。这两个配置类的基本软件包都相同。
我是否还需要在排除和包含过滤器上指定RestControllerAdvice
?还是我想念其他东西?
编辑:
两个@RestControllerAdvice
都没有basePackeges
或任何特定条件。
而ServiceException
实际上是已找到并注册的。
如果我将异常处理程序移至工作处理程序,则调用该异常处理程序。
这就是我的工作方式。如果我将ServiceException
处理程序移到一个单独的类中,则不会再调用它。
@RestControllerAdvice
public class GlobalRestControllerAdviser extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleBindException(
final BindException ex,
final HttpHeaders headers,
final HttpStatus status,
final WebRequest request) {
return new ResponseEntity<Object>(
buildPresentableError(ex.getAllErrors().get(0)),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ServiceException.class)
protected Response<?> handleServiceException(final ServiceException e) {
...
}
@ExceptionHandler(Exception.class)
protected ResponseEntity<Object> handleGenericException(final Exception ex) {
...
}
}
好像最通用的ExceptionHandler
覆盖了更具体的那个。
答案 0 :(得分:3)
几乎在这里,使用FilterType type
并分离过滤器。
@Configuration
@ComponentScan(
basePackages = { ... },
excludeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class),
@ComponentScan.Filter(type=FilterType.ANNOTATION, value=ControllerAdvice.class)
}
)
或者,我建议您创建一个自定义注释(例如@FrontEnd
)并将过滤器应用于该注释。
答案 1 :(得分:0)
基本上,@ControllerAdvice
个带注释的类是有序的,这意味着如果Spring内部人员发现一个@ExceptionHandler
接受抛出的异常,它将使用该异常并停止。
具有多个类时,可以使用@Order
设置Bean优先级(例如)。用ServiceException
注释包含@Order
的类使其生效。
此外,根据此功能请求https://jira.spring.io/browse/SPR-8881,我们可以在一个@Filter
批注上指定多个类,而无需将它们分成多个@Filter
。