主要是解决以下问题:
- 用户输入不存在的url;必需参数未传
- 服务器异常
解决方法:
- 在templates文件夹下,直接创建error页面,这样所有异常将直接转到这个页面
- 在templates文件夹下,直接创建error文件夹。在error文件夹里,创建404.html,500.html 这种以http错误值为名称的页面。此时,当产生某种错误时,将直接跳到相应页面。
同时使用时,以2为准
分析:
- 先看ErrorMvcAutoConfiguration,由注解可知,当注册dispatcherServlet加载时,会自动加载这个类。
- 当没有类实现ErrorController接口时,会注册一个BasicErrorController。所以,如果不想使用springboot提供的默认配置,也可以自己实现ErrorController接口,继承后默认配置不再生效
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureBefore({WebMvcAutoConfiguration.class})
@EnableConfigurationProperties({ResourceProperties.class})
public class ErrorMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean(
value = {ErrorController.class},
search = SearchStrategy.CURRENT
)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers);
}
- BasicController默认的url是“error”,修改配置文件的server.error.path可以修改。
@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
}
- resolveErrorView方法在父类中,此方法主要用于根据http错误码返回相应的modelAndView
protected ModelAndView resolveErrorView(HttpServletRequest request,
HttpServletResponse response, HttpStatus status, Map<String, Object> model) {
for (ErrorViewResolver resolver : this.errorViewResolvers) {
ModelAndView modelAndView = resolver.resolveErrorView(request, status, model);
if (modelAndView != null) {
return modelAndView;
}
}
return null;
}
- resolverErrorView方法在DefaultErrorViewResolver中
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,
Map<String, Object> model) {
ModelAndView modelAndView = resolve(String.valueOf(status), model);
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
}
return modelAndView;
}
- resolve
private ModelAndView resolve(String viewName, Map<String, Object> model) {
String errorViewName = "error/" + viewName;
TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
.getProvider(errorViewName, this.applicationContext);
if (provider != null) {
return new ModelAndView(errorViewName, model);
}
return resolveResource(errorViewName, model);
}
由此方法可知404错误,直接对应/error/404页面。
由于我使用的是thymeleaf,所以provider并不是空。如果项目中没有使用jsp,thymleaf,groovy,freemarker等引擎模板,会导致provider未空,则不能返回相应的错误页面。