如何将 Spring 配置错误处理重定向到我的自定义配置?



我想知道是否有一种聪明的方法可以通过配置来处理 Spring 中的异常。我可以直接从扩展 WebSecurityConfigurerAdapter 接口的类中抛出异常,但在我看来,如果我使用 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()

问题是如果我引发异常,它由默认的异常处理处理,我无法设置自定义错误消息或 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);
}

}

异常处理程序

@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 的堆栈跟踪是

com.application.controller.user.UserNotFoundException: no User found with this email / password combination
....

但是使用 conf 我收到 403 错误而不是 500(会改变但想要不同的错误代码(并且正文是空的。 我怎样才能将两者结合起来?我对受保护的路由有同样的问题,如果记录用户并让 Spring 为我做,我不想在每个控制器中的每个函数中处理异常,只需将其重定向到我的自定义异常服务即可。 提前致谢

在 ExceptionHandler Advice 中,您需要将 ApiErrorResponse 包装到 ResponseEntity 中并返回新的 ResponseEntity<>(new ApiErrorResponse(ex.getMessage(((,HttpStatus.BAD_REQUEST(;

最新更新