在我的 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 由于 @RequestMapping("/error")
调用 handleError
方法,但在这种情况下,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() - 返回:导致错误的异常或 null。
关于java - Spring Boot - 处理未找到的静态资源(404)并能够识别异常原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62416027/