form1.cn
Make a little progress every day

SpringBoot自定义404、500等错误页面,解决war包后不起作用

26th of July 2017 Java Java 4337

本文使用的方式是拦截器,本人也使用过以下方式:

//使用这种方式,在打包为war后不起作用
//@Configuration
public class ErrorPageConfig implements EmbeddedServletContainerCustomizer {
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        container.addErrorPages(
                new ErrorPage(HttpStatus.BAD_REQUEST, "/4O0.html"),
                new ErrorPage(HttpStatus.UNAUTHORIZED, "/4O1.html"),
                new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"),
                new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html")
        );
    }
}

注:这种方式,使用Springboot内置的Tomcat是没问题,可当你打成war包,发布到自己的Tomcat的时候就会失效,不知道为啥



以下是使用拦截器的方式,根据http状态码拦截对应的错误页面


第一步:创建我们自己的拦截器类并实现 HandlerInterceptor 接口。 

/**
  创建一个拦截器,拦截Controller
  需要实现 HandlerInterceptor 接口
 /
public class MyHandleInterceptor implements HandlerInterceptor {
    /
     在Controller调用之前运行
     return false 将不会执行任何控制
     /
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("==preHandle:在Controller调用之前运行==" + o.getClass());
        return true;
    }
    /
     在Controller调用之后 且 页面渲染之前运行
     /
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("==postHandle:在Controller调用之后 且 页面渲染之前运行==" + o.getClass()+"-----"+httpServletResponse.getStatus());
        if(httpServletResponse.getStatus()==500){
            modelAndView.setViewName("pages/500");
        }else if(httpServletResponse.getStatus()==400){
            modelAndView.setViewName("pages/400");
        }else if(httpServletResponse.getStatus()==401){
            modelAndView.setViewName("pages/401");
        }else if(httpServletResponse.getStatus()==404){
            modelAndView.setViewName("pages/404");
        }
    }
    /
     在Controller调用之后 且 页面渲染之后运行,一般进行清理资源操作
     /
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("==afterCompletion:在Controller调用之后 且 页面渲染之后运行==" + o.getClass());
    }
}


第二步:添加并触发拦截器的类 

/**
  添加并触发拦截器的类
 /
@SpringBootConfiguration
public class Webconfiguration extends WebMvcConfigurerAdapter{
    /
     覆盖父类addInterceptors方法,来添加拦截器类
     /
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyHandleInterceptor());
    }
}


到这里拦截器就基本实现了,当然那些html页面你肯定得自己搞定


不过需要注意的是,这种拦截有时候也会出现特别大问题。例如一个网页中如果需要加载很多的图片或者js文件资源,可是正好没有这个资源,也就是找不到这么多个资源报一堆的404错误。这个时候如果还是单纯的使用这种拦截就会出现null指针异常的情况。

针对这种情况,我研究了一种方法可以解决这样类似的问题。

解决方案就是:创建一个类并实现ErrorController接口,这样就可以利用这个类来处理上面发生的问题了。

下面给出代码:

package example.controller;  
import org.springframework.boot.autoconfigure.web.ErrorController;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
@Controller  
public class MainsiteErrorController implements ErrorController {  
    private static final String ERROR_PATH = "/error";  
    @RequestMapping(value=ERROR_PATH)  
    public String handleError(){  
        return "errorpage/error";  
    }  
    @Override  
    public String getErrorPath() {  
        return ERROR_PATH;  
    }  
}


参考链接:http://blog.csdn.net/linzhiqiang0316/article/details/52600839