配置异常映射机制

作用:将捕获到的异常类型和具体页面对应起来。在捕获到对应类型的异常后,跳转到对应页面。
配置:XML方式(只能返回页面,很难兼容Ajax请求)
配置:Annotation方式(兼容两种请求)

1、后端:异常处理器

@ControllerAdvice
public class CrowdFundingExceptionResolever {
	
	@ExceptionHandler(value=Exception.class)
	public ModelAndView catchException(Exception exception) {
		
		ModelAndView mav = new ModelAndView();
		//存错误信息
		mav.addObject("exception", exception);
		//出错去往的页面 system-error.jsp
		mav.setViewName("system-error");
		
		return mav;
	}

}

mav.addObject(“exception”, exception):存的是错误信息。
mav.setViewName(“system-error”):存的是错误以后去往的页面
  如果存储的错误信息不重写的话,错误页面显示的就是具体的错误信息,客户感官不好,
在这里插入图片描述

2、前端:错误信息页面

<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
	$(function(){
		$("#bakcBtn").click(function(){
			//返回到前一个页面
			window.history.back();
		});
	});
</script>
<!-- 取错误信息 -->
<h1>${requestScope.exception.message }</h1>
<button id="bakcBtn" class="btn btn-lg btn-success btn-block">后退</button>

3、错误测试

故意新增一个存在的信息,我们可以指定报错的具体信息,可以自定义一个提示。

	//新增
	@RequestMapping("/admin/save")
	public String saveAdmin(Admin admin) {
		
		try {
			adminService.saveAdmin(admin);
		} catch (Exception e) {
			e.printStackTrace();
			//针对DuplicateKeyException这个异常,提示用户已存在,
			if(e instanceof DuplicateKeyException) {
				throw new RuntimeException("用户已存在!");
			}
		}
		
		return "redirect:/admin/query/for/search.html";
	}

在这里插入图片描述

4、异常映射兼容异步请求

在这里插入图片描述
  目前这个异常处理机制,只能处理页面,对ajax的错误是无效的,ajax错误的话,只会在控制台报错,而不会在页面显示。所以ajax如果报错了,导致页面不能正常显示,不友好,怎么解决呢?

4.1 分辨异步请求和同步请求

4.1.1 pom依赖

  在异常处理中判断它是同步请求还是异步请求,需要用到HttpServletRequest,导入依赖

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>

4.1.2 判断是否异步请求工具类

	/**
	 * 判断请求是否为异步请求
	 * 
	 * @param request
	 * @return
	 */
	public boolean checkAsyncRequest(HttpServletRequest request) {
		//获取相应请消息头
		String accept = request.getHeader("Accept");
		String xRequested = request.getHeader("X-Requested-With");
		//判断请求消息头是否包含json的特征
		if (stringEffective(accept) && accept.contains("application/json")
				|| stringEffective(xRequested) && xRequested.contains("XMLHttpRequest")) {
			return true;
		}
		return false;
	}
	
	/**
	 * 判断字符串是否有效
	 * 
	 * @param source 待验证字符串
	 * @return true表示有效,false表示无效
	 */
	public boolean stringEffective(String source) {

		return source != null && source.length() > 0;
	}

4.2 修改异常处理器

4.2.1 pom依赖

这里需要转换JSON,导入JSON包,这里用的是google的

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
</dependency>

4.2.2 JSON响应格式的实体类

  这里用了lombok,注释是lombok帮助生成了get和set方法,以及全参和无参构造函数,没有lombok就自己写get和set方法,以及全参和无参构造函数

/**
 * ajax请求的响应格式
 * 
 * @author Administrator
 *
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ResultEntity<T> {

	public static final String SUCCESS = "SUCCESS";
	public static final String FAILED = "FAILED";
	public static final String NO_MESSAGE = "NO_MESSAGE";
	public static final String NO_DATA = "NO_DATA";

	// 方便返回成功结果(不携带查询结果情况)
	public static ResultEntity<String> successWithoutData() {
		return new ResultEntity<String>(SUCCESS, NO_MESSAGE, NO_DATA);
	}
	
	// 方便返回成功结果(携带查询结果情况)
	public static <E> ResultEntity<E> successWithData(E data) {
		return new ResultEntity<E>(SUCCESS, NO_MESSAGE, data);
	}
	
	// 方便返回失败结果
	public static <E> ResultEntity<E> failed(E data, String message) {
		return new ResultEntity<E>(FAILED, message, data);
	}

	private String result;
	private String message;
	private T data;

}

4.2.3 改进后的异常处理器

	@ExceptionHandler(value = Exception.class)
	public ModelAndView catchException(Exception exception,HttpServletRequest request,HttpServletResponse response) throws IOException {
		//判断请求是否为异步
		boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);
		//如果是异步请求
		if(checkAsyncRequestResult) {
			//创建ResultEntity对象,exception.getMessage()就是报错的异常信息,你也可以自己写,
			//ResultEntity<String> resultEntity =ResultEntity.failed(ResultEntity.NO_DATA, "发生错误了");
			ResultEntity<String> resultEntity =ResultEntity.failed(ResultEntity.NO_DATA, exception.getMessage());
			//ResultEntity对象转为JSON对象
			Gson gson = new Gson();
			String json = gson.toJson(resultEntity);
			//将JSON作为相应数据返回给浏览器
			response.setContentType("application/json;charset=UTF-8");
			response.getWriter().write(json);
			
			return null;
		}
		
		ModelAndView mav=new ModelAndView();
		mav.addObject("exception",exception);
		mav.setViewName("system-error");
		
		return mav;
	}

这是用layer写的,就是这个样式,没有layer的话,可以直接alert查看报错信息
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值