SpringMVC--通过Controller设置400/404/500自定义错误页面

一、说明

web系统开发过程中经常遇见400/404/500类型的错误页面,对于开发人员而言见到这种页面多了可能觉得问题不大,但是实际是很重要的,需要配置一个合理的自定义错误页面。

本文只提通过springmvc controller配置自定义错误页,Tomcat设置400/404/500自定义错误页面(推荐)请参考博文:点击打开链接

二、实现

1.spring-mvc.xml(视图解析器配置)

<!--视图解析器--> 
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	 <property name="suffix" value=".jsp"></property>
	 <property name="prefix" value="/WEB-INF/views/"></property> 
</bean>

2.ErrorController.java(代码实现)

package com.mvc.pab.internet.controller;


import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("error")
public class ErrorController {
	private static final String BASE_DIR = "error/";
	@RequestMapping("400")
	public String handle1(HttpServletRequest request){
		return BASE_DIR + "400";
	}
	@RequestMapping("404")
	public String handle2(HttpServletRequest request){
		return BASE_DIR + "404";
	}
	@RequestMapping("500")
	public String handle3(HttpServletRequest request){
		return BASE_DIR + "500";
	}
}

3.web.xml(错误页面路径定义)

<error-page>
		<error-code>400</error-code>
		<location>/error/400</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/error/404</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/error/500</location>
</error-page>

3.spring-mvc.xml(拦截器配置)

项目当中有设置全局拦截器的,一定要在这里添加拦截器配置,不然会被拦截,配置方法是往自己的配置中节点代码<mvc:exclude-mapping path="/error/*" />/error/*为我的错误页的视图层,意为都不拦截/error/

<!--配置拦截器, 多个拦截器,顺序执行 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
			<mvc:mapping path="/**" />
			<mvc:exclude-mapping path="/error/*" />
			<mvc:exclude-mapping path="/test/*" />
			<mvc:exclude-mapping path="/manager/*" />
			<mvc:exclude-mapping path="/wxmanager/*" />
			<bean class="com.mvc.filter.CommonInterceptor"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
			<mvc:mapping path="/manager/*" />
			<mvc:mapping path="/wxmanage/*" />
			<mvc:exclude-mapping path="/manager/login" />
			<mvc:exclude-mapping path="/manager/doLogin" />
			<bean class="com.mvc.filter.ManagerInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

重启服务器生效!!!!

附文章ManagerInterceptor.java示例

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.mvc.pab.model.Account;
import com.mvc.security.model.User;

public class ManagerInterceptor extends HandlerInterceptorAdapter {
	private final Logger log = LoggerFactory.getLogger(ManagerInterceptor.class);
	
	
	
	 /** 
     * 在业务处理器处理请求之前被调用 
     * 如果返回false 
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * 如果返回true 
     *    执行下一个拦截器,直到所有的拦截器都执行完毕 
     *    再执行被拦截的Controller 
     *    然后进入拦截器链, 
     *    从最后一个拦截器往回执行所有的postHandle() 
     *    接着再从最后一个拦截器往回执行所有的afterCompletion() 
     */  
    @Override  
    public boolean preHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler) throws Exception {  
        log.info("==============执行顺序: 1、preHandle================");  
		String requestUri = request.getRequestURI();
		String contextPath = request.getContextPath();
		String url = requestUri.substring(contextPath.length());
      
        log.info("requestUri:"+requestUri);  
        log.info("contextPath:"+contextPath);  
        log.info("url:"+url);  
        //String token =  (String)request.getSession().getAttribute("token");
        User admin =  (User)request.getSession().getAttribute("admin");
        if(admin == null){
        	//异步请求
	        if(request.getHeader("x-requested-with")!=null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
				response.getWriter().print("timeout");
				return false;
			}else{
				log.info("Interceptor:跳转到login页面!");
	        	response.sendRedirect("../manager/login");
	        	return false;
			}
        
        	
        }else if (! (admin.getType() == 1)) {//拦截高尔夫和机场的管理用户,只能查询订单和确认到场
        		if ( ! (url.equals("/manager/search") || url.equals("/manager/getOrder")  || url.equals("/manager/confirmUser")  || url.equals("/manager/golfPage")  || url.equals("/manager/airPage") || url.equals("/manager/logout") || url.equals("/manager/airOrder") || url.equals("/manager/golfOrder"))) {
        			response.sendRedirect("../manager/login");
					return false;
				}
			 return true;
		}else{
        	
        	return true;   
        }
    }  
    
    /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作   
     * 可在modelAndView中加入数据,比如当前时间
     */
    @Override  
    public void postHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler,  
            ModelAndView modelAndView) throws Exception {   
        log.info("==============执行顺序: 2、postHandle================");  
        if(modelAndView != null){  //加入当前时间  
//            modelAndView.addObject("var", "测试postHandle");  
        }  
    }  
  
    /** 
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等  
     *  
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion() 
     */  
    @Override  
    public void afterCompletion(HttpServletRequest request,  
            HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
        log.info("==============执行顺序: 3、afterCompletion================");  
    }  

}

CommonIntercetor.java示例代码

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.mvc.framework.util.DomainUtils;
import com.mvc.pab.internet.controller.AccountController;
import com.mvc.pab.model.Account;
import com.mvc.soecode.wxtools.api.IService;
import com.mvc.soecode.wxtools.api.WxConsts;
import com.mvc.soecode.wxtools.api.WxService;
import com.soecode.wxtools.bean.WxUserList.WxUser;

/**
 * @author justin 2017-8-1
 */
public class CommonInterceptor extends HandlerInterceptorAdapter {
	private final Logger log = Logger.getLogger(CommonInterceptor.class);
	public static final String LAST_PAGE = "com.alibaba.lastPage";

	/*
	 * 利用正则映射到需要拦截的路径
	 * 
	 * private String mappingURL;
	 * 
	 * public void setMappingURL(String mappingURL) { this.mappingURL =
	 * mappingURL; }
	 */
	/**
	 * 在业务处理器处理请求之前被调用 如果返回false 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
	 * 如果返回true 执行下一个拦截器,直到所有的拦截器都执行完毕 再执行被拦截的Controller 然后进入拦截器链,
	 * 从最后一个拦截器往回执行所有的postHandle() 接着再从最后一个拦截器往回执行所有的afterCompletion()
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		log.info("==============执行顺序: 1、preHandle================");
		String requestUri = request.getRequestURI();
		String contextPath = request.getContextPath();
		String url = requestUri.substring(contextPath.length());

		log.info("requestUri:" + requestUri);
		log.info("contextPath:" + contextPath);
		log.info("url:" + url);
		String token = (String) request.getSession().getAttribute("token");
		WxUser wxUser = (WxUser) request.getSession().getAttribute("wxUser");
		Account user = (Account) request.getSession().getAttribute("user");

		if (null == wxUser) {// 需要授权登录
			if (request.getHeader("x-requested-with") != null
					&& request.getHeader("x-requested-with").equalsIgnoreCase(
							"XMLHttpRequest")) {
				response.getWriter().print("timeout");
				return false;
			} else {
				IService wxService = new WxService();
				String oauth_url = wxService.oauth2buildAuthorizationUrl(
						AccountController.REDIRECT_URL,
						WxConsts.OAUTH2_SCOPE_USER_INFO, "");
				response.sendRedirect(oauth_url);
				return false;
			}
		}

		if (user == null) {// 未验证身份证
			// 异步请求
			if (request.getHeader("x-requested-with") != null
					&& request.getHeader("x-requested-with").equalsIgnoreCase(
							"XMLHttpRequest")) {
				response.getWriter().print("timeout");
				return false;
			} else {
				log.info("Interceptor:跳转到用户首页面!");
				response.sendRedirect(DomainUtils.getDynamicDomain()
						+ "/account/index");
				return false;
			}

		} else
			return true;
	}

	/**
	 * 在业务处理器处理请求执行完成后,生成视图之前执行的动作 可在modelAndView中加入数据,比如当前时间
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		log.info("==============执行顺序: 2、postHandle================");
		if (modelAndView != null) { // 加入当前时间
		// modelAndView.addObject("var", "测试postHandle");
		}
	}

	/**
	 * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
	 * 
	 * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		log.info("==============执行顺序: 3、afterCompletion================");
	}

}

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾日三省贾斯汀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值