SpringMVC里面并没有对于这样404错误处理的任何有效支持,在我们没有配置任何404页面的情况下,tomcat默认提供一个,所以如果要想使用,就必须改写“源代码”,通过继承的形式进行某些方法的重写即可
首先来打开DispatcherServlet的源代码
在SpringMVC中我们所有的请求最终都会到DispatcherServlet前端控制器中,她也为我们提供这样一个方法
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (pageNotFoundLogger.isWarnEnabled()) {//日志信息
pageNotFoundLogger.warn("No mapping for " + request.getMethod() + " " + getRequestUri(request));
}
if (this.throwExceptionIfNoHandlerFound) {//是否有异常
throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request),
new ServletServerHttpRequest(request).getHeaders());
}
else {//实现跳转的方法
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
1.通过继承DispatcherServlet重写此方法,来自定义跳转的页面
public class NoHandlerFoundDispatcherServlet extends DispatcherServlet {//自定义分发控制器
public NoHandlerFoundDispatcherServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);//调用父类构造
}
@Override//根据需要进行重写
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.sendRedirect("/nofound");//进行未发现路径的配置,表示重定向
}
}
2.修改配置类(采用注解),重写createDispatcherServlet()方法,相当于使用我们自己定义的前端控制器
public class StartWebApplication extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected FrameworkServlet createDispatcherServlet(
WebApplicationContext servletAppContext) {//分发控制器的创建
return new NoHandlerFoundDispatcherServlet(servletAppContext);
}//重写
@Override
protected Class<?>[] getRootConfigClasses() {// 获取Spring容器的启动类
return new Class[]{SpringApplicationContextConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {// SpringWeb容器启动类
return new Class[]{SpringWEBContextConfig.class};
}
@Override
protected String[] getServletMappings() {// DispatcherServlet分发处理
return new String[]{"/"};
}
.....
}
3.定义Controller进行跳转
@Controller
public class NotFoundAction {//未发现
//与自定义DispatcherServlet类中的路径相同
@RequestMapping("/nofound")
public String noFound(){
return "/nofound";//这里返回的是真正的页面视图,已经定义了视图资源解析器
}
}
4.配置
SpringWEBContextConfig配置
@Configuration
@ComponentScan({"cn.shun.controller"})
@EnableWebMvc//加入此注解,采才表示WebMVC配置类有效
public class SpringWEBContextConfig implements WebMvcConfigurer { // WEB上下文配置类
/**
* 配置视图资源解析器
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages");
resolver.setSuffix(".jsp");
registry.viewResolver(resolver);
}
/**
* 添加资源映射
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("shun-js/**").addResourceLocations("/WEB-INF/static/js/");
registry.addResourceHandler("shun-css/**").addResourceLocations("/WEB-INF/static/css/");
registry.addResourceHandler("shun-images/**").addResourceLocations("/WEB-INF/static/images/");
}
}
这是webapp结构
错误页面nofound.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>页面出错了</h1>
<img src="/shun-images/404.jpg">
</body>
</html>
效果展示