在我的Spring Boot应用程序(2.3.1.RELEASE)中,我使用以下方法提供静态资源:

@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/static/favicon.ico");
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
}


这很好。但是我无法正确管理未找到的静态资源。我希望在发生这种情况时调用自定义处理程序。

在我的应用程序中,我当前的策略是用一种方法来管理所有异常。这是我目前正在做的事情:

@ControllerAdvice
@RestController
public class AppErrorController implements ErrorController {

    @Autowired
    private ErrorAttributes errorAttributes;

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @ExceptionHandler(Exception.class)
    @RequestMapping("/error")
    public ErrorResponse handleError(WebRequest webRequest, HttpServletRequest request, HttpServletResponse response) {

        // Get access to the actual Exception
        Throwable ex = this.errorAttributes.getError(webRequest);

        // Check if it is a 404 exception
        if (ex != null && instanceof NoHandlerFoundException) {
            // Manage the error as a 404!
            // ...
        } else {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            ErrorResponse errorResponse = new ErrorResponse("generalError", "An error occured");
            return errorResponse;
        }
    }
}


除一种情况外,此方法运行良好:找不到静态资源! Spring然后由于handleError调用@RequestMapping("/error")方法,但是在这种情况下,this.errorAttributes.getError(webRequest)返回的异常是null!所以我不知道它实际上是404,因此我的代码返回了一般的500错误。

我如何处理对不存在的静态资源的请求并能够确定原因,所以我可以返回404而不是500?

编辑:

我在application.properties中使用这些配置:

spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true

最佳答案

通过将请求转发到Servlet容器的“默认” Servlet,配置用于处理静态资源的请求处理程序。 DefaultServletHandlerConfigurer

@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/favicon.ico").addResourceLocations("/static/favicon.ico");
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/resources/static/index.html");
        registry.addViewController("/error").setViewName("forward:/resources/error/404.html");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
   }
}


或使用ControllerAdvice。

@Slf4j
@Order(ORDER)
@RestControllerAdvice(annotations = RestController.class)
public class GlobalRestControllerAdvice {

    public static final int ORDER = 0;

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NotFoundException.class)
    public Map<String, String> handle(NotFoundException e) {
        log.error(e.getMessage(), e);
        Map<String, String> errorAttributes = new HashMap<>();
        errorAttributes.put("code", "NOT_FOUND");
        errorAttributes.put("message", e.getMessage());
        return errorAttributes;
    }
}

@Slf4j
@Order(GlobalRestControllerAdvice.ORDER + 1)
@ControllerAdvice
public class GlobalHtmlControllerAdvice {

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NotFoundException.class)
    public String handle(NotFoundException e, Model model, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        model.addAttribute("timestamp", LocalDateTime.now());
        model.addAttribute("error", "NOT_FOUND");
        model.addAttribute("path", request.getRequestURI());
        model.addAttribute("message", e.getMessage());
        return "/error/404";
    }
}


ErrorAttributes getError()-返回:导致错误的Exception或null。

关于java - Spring Boot-处理找不到的静态资源(404)并能够识别异常原因,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62416027/

10-16 22:32