在我的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/