Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 服务中引发异常时的Spring引导异常处理程序_Java_Spring_Spring Boot_Exception - Fatal编程技术网

Java 服务中引发异常时的Spring引导异常处理程序

Java 服务中引发异常时的Spring引导异常处理程序,java,spring,spring-boot,exception,Java,Spring,Spring Boot,Exception,我正在使用ControllerAdvice处理spring引导应用程序中的异常 @Order(Ordered.HIGHEST_PRECEDENCE) @ControllerAdvice public class ErrorApiHandler extends ResponseEntityExceptionHandler { final ResponsesHelper rh; public ErrorApiHandler(ResponsesHelper rh) {

我正在使用ControllerAdvice处理spring引导应用程序中的异常

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class ErrorApiHandler extends ResponseEntityExceptionHandler {

    final
    ResponsesHelper rh;

    public ErrorApiHandler(ResponsesHelper rh) {
        this.rh = rh;
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public ResponseEntity<Object> handleUsernameNotFoundException(UsernameNotFoundException ex) {
    log.error(ExceptionUtils.getStackTrace(ex));

    var error = buildError(ex);
    return rh.buildResponse(error, HttpStatus.NOT_FOUND);
    }
...
}
@顺序(有序。最高优先级)
@控制器建议
公共类ErrorApiHandler扩展了ResponseEntityExceptionHandler{
最终的
响应帮助rh;
公共错误处理程序(ResponseHelper rh){
这个。相对湿度=相对湿度;
}
@ExceptionHandler(UsernameNotFoundException.class)
公共响应handleUsernameNotFoundException(UsernameNotFoundException ex){
log.error(ExceptionUtils.getStackTrace(ex));
var错误=构建错误(ex);
返回rh.buildResponse(错误,HttpStatus.NOT_FOUND);
}
...
}
它可以很好地处理控制器中抛出的异常。 但是,如果抛出异常,例如在服务中,则不会执行ControllerAdvice

@Service
public class CustomUserDetailsService implements UserDetailsService {

    final
    UserRepository userRepository;

    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional
    public User loadUserByUsername(String email)
            throws UsernameNotFoundException {

        log.debug(String.format("Loading user %s", email));

        User user = userRepository.findByEmail(email)
                .orElseThrow(() -> {

                    log.debug(String.format("User %s not found", email));
                    return new UsernameNotFoundException("User not found : " + email); // <- This exception is not handled.
                });

        log.debug(String.format("User %s loaded", user));
        return user;
    }
@服务
公共类CustomUserDetailsService实现UserDetailsService{
最终的
用户存储库用户存储库;
公共CustomUserDetailsService(用户存储库用户存储库){
this.userRepository=userRepository;
}
@凌驾
@交易的
公共用户loadUserByUsername(字符串电子邮件)
抛出UsernameNotFoundException{
log.debug(String.format(“正在加载用户%s”,电子邮件));
User=userRepository.findByEmail(电子邮件)
.orElseThrow(()->{
log.debug(String.format(“未找到用户%s”,电子邮件));

返回新的UsernameNotFoundException(“未找到用户:+电子邮件”);//
@ControllerAdvice
用于处理通过控制器方法传播的异常(从控制器方法调用中抛出的异常-包括冒泡异常)所以,每当您直接在控制器方法中抛出异常,或者控制器方法正在调用的东西抛出异常时,都会尝试通过建议来处理它


如果您希望在web上下文之外以类似的方式(以某种方式)处理您的异常,您必须编写自己的方面,将所有内容包装为try catch,并允许您处理异常。

我在ResponseEntityExceptionHandler文档中发现了这一点:

为@ControllerAdvice类提供了一个方便的基类,这些类希望通过@ExceptionHandler方法跨所有@RequestMapping方法提供集中的异常处理

扩展该类的自定义异常处理程序似乎只处理控制器层中的异常

我发现-使用HandlerExceptionResolver的解决方案听起来像是您正在寻找的解决方案。

在我的例子中,我的“CustomUserDetailsService”是在筛选器中调用的:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain
        ) throws ServletException, IOException {

        try {
            String jwt = getJwtFromRequest(request);

            if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
                UUID userId = tokenProvider.getUserIdFromJWT(jwt);

                UserDetails userDetails = customUserDetailsService.loadUserById(userId);
...
我通过捕捉异常来处理它:

catch (UsernameNotFoundException ex){
            log.error(ExceptionUtils.getStackTrace(ex));

            var apiError = ErrorApiHandler.buildError(
                    new ResourceAlreadyTakenException(ex.getMessage())
            );

            response.addHeader("Content-Type", "application/json");
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            PrintWriter writer = response.getWriter();
            writer.write(convertObjectToJson(apiError));
            writer.flush();
            return;
        }

理想情况下,使用控制器建议处理所有异常,但这样它就可以工作了

我们谈论的是链式REST->WebController->Service->Exception吗?这是否有帮助: