如何将 Spring 配置错误处理重定向到我的自定义错误处理?
How to redirect Spring configuration error handling to my custom one?
想知道有没有什么巧妙的方法可以通过配置来处理Spring中的异常。我可以直接从扩展 WebSecurityConfigurerAdapter 接口的 class 抛出异常,但在我看来,如果我使用 exceptionHandling 方法,我就不能用它发送消息。但是,如果我删除 conf,我将无法进行全局自定义异常配置。我想知道 Spring 是否可以将异常处理重定向到 @ControllerAdvice?
现在我的代码看起来像这样(我从代码中删除了无用的部分)
配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@FieldDefaults(level = PRIVATE, makeFinal = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthFailureHandler authFailureHandler;
private static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("**", "OPTIONS"), // allow prefligh for now in debug
new AntPathRequestMatcher("/public/**")
);
private static final RequestMatcher PROTECTED_URLS = new NegatedRequestMatcher(PUBLIC_URLS);
TokenAuthenticationProvider provider;
SecurityConfig(AuthFailureHandler authFailureHandler, final TokenAuthenticationProvider provider) {
super();
this.authFailureHandler = authFailureHandler;
this.provider = requireNonNull(provider);
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(provider);
}
@Override
public void configure(final WebSecurity web) {
web.ignoring().requestMatchers(PUBLIC_URLS);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
.and()
.authenticationProvider(provider)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
}
这里处理异常的代码是
.exceptionHandling()
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
.and()
.authenticationProvider(provider)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
问题是如果我引发异常,它由默认的 ExceptionHandling 处理,我无法设置自定义错误消息或 http 错误代码,导致默认错误处理。如果我删除它,我必须在所有地方引发异常!
一个控制器
许多中的一个,但像这样你有一个样本
@RestController
@RequestMapping("/public/users")
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@CrossOrigin
public class UserPublic {
@NonNull UserAuthenticationService authenticationService;
@PostMapping(value = "/login",
consumes="application/json",
produces="application/json")
UserDTO login(@RequestBody shortDTO dto) throws UserNotFoundException {
UserDTO userDTO = authenticationService.login(dto.email, dto.password);
if (userDTO == null) throw new UserNotFoundException("no User found with this email / password combination");
return userDTO;
}
异常
public class UserNotFoundException extends Exception {
public UserNotFoundException(String no_user_found) {
super(no_user_found);
}
}
ExceptionHandler
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {UserNotFoundException.class })
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiErrorResponse unknownException(Exception ex, WebRequest req) {
System.out.println("damn here we go again");
ex.printStackTrace();
return new ApiErrorResponse(ex.getMessage());
}
}
启用或禁用 conf 的 StackTrace 是
com.application.controller.user.UserNotFoundException: no User found with this email / password combination
....
但是使用 conf 我收到 403 错误而不是 500(将更改但需要不同的错误代码)并且正文是空的。
我怎样才能将两者结合起来?对于受保护的路由,我有同样的问题,如果用户已登录并让 Spring 为我处理,我不想在每个控制器的每个函数中处理异常,只需将其重定向到我的自定义异常服务。
提前致谢
在您的 ExceptionHandler 建议中您需要将 ApiErrorResponse 包装到 ResponseEntity 和 return new ResponseEntity<>(new ApiErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
想知道有没有什么巧妙的方法可以通过配置来处理Spring中的异常。我可以直接从扩展 WebSecurityConfigurerAdapter 接口的 class 抛出异常,但在我看来,如果我使用 exceptionHandling 方法,我就不能用它发送消息。但是,如果我删除 conf,我将无法进行全局自定义异常配置。我想知道 Spring 是否可以将异常处理重定向到 @ControllerAdvice?
现在我的代码看起来像这样(我从代码中删除了无用的部分)
配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@FieldDefaults(level = PRIVATE, makeFinal = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthFailureHandler authFailureHandler;
private static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("**", "OPTIONS"), // allow prefligh for now in debug
new AntPathRequestMatcher("/public/**")
);
private static final RequestMatcher PROTECTED_URLS = new NegatedRequestMatcher(PUBLIC_URLS);
TokenAuthenticationProvider provider;
SecurityConfig(AuthFailureHandler authFailureHandler, final TokenAuthenticationProvider provider) {
super();
this.authFailureHandler = authFailureHandler;
this.provider = requireNonNull(provider);
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(provider);
}
@Override
public void configure(final WebSecurity web) {
web.ignoring().requestMatchers(PUBLIC_URLS);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
.and()
.authenticationProvider(provider)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
}
这里处理异常的代码是
.exceptionHandling()
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
.and()
.authenticationProvider(provider)
.authorizeRequests()
.requestMatchers(PROTECTED_URLS)
.authenticated()
问题是如果我引发异常,它由默认的 ExceptionHandling 处理,我无法设置自定义错误消息或 http 错误代码,导致默认错误处理。如果我删除它,我必须在所有地方引发异常!
一个控制器 许多中的一个,但像这样你有一个样本
@RestController
@RequestMapping("/public/users")
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@CrossOrigin
public class UserPublic {
@NonNull UserAuthenticationService authenticationService;
@PostMapping(value = "/login",
consumes="application/json",
produces="application/json")
UserDTO login(@RequestBody shortDTO dto) throws UserNotFoundException {
UserDTO userDTO = authenticationService.login(dto.email, dto.password);
if (userDTO == null) throw new UserNotFoundException("no User found with this email / password combination");
return userDTO;
}
异常
public class UserNotFoundException extends Exception {
public UserNotFoundException(String no_user_found) {
super(no_user_found);
}
}
ExceptionHandler
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {UserNotFoundException.class })
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiErrorResponse unknownException(Exception ex, WebRequest req) {
System.out.println("damn here we go again");
ex.printStackTrace();
return new ApiErrorResponse(ex.getMessage());
}
}
启用或禁用 conf 的 StackTrace 是
com.application.controller.user.UserNotFoundException: no User found with this email / password combination
....
但是使用 conf 我收到 403 错误而不是 500(将更改但需要不同的错误代码)并且正文是空的。 我怎样才能将两者结合起来?对于受保护的路由,我有同样的问题,如果用户已登录并让 Spring 为我处理,我不想在每个控制器的每个函数中处理异常,只需将其重定向到我的自定义异常服务。 提前致谢
在您的 ExceptionHandler 建议中您需要将 ApiErrorResponse 包装到 ResponseEntity 和 return new ResponseEntity<>(new ApiErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);