提示:可能对很多人来说码周记中的内容比较菜,不喜勿喷!!!
本周想分享以下几个内容:
我相信对于很多人初学者来说甚至都没有见过这个异常,这个东西是springMV中web.util下面的。
据我所知:
如果有异常没有在controller层处理掉的话,就会被springmvc的这个异常捕获处理,然后前端就会出现一个很长的异常(这个个人觉得还可以接受),比如:Request processing failed; nested exception is java.lang.ArithmeticException: / by zero…
如果我们在项目中用到了aop,然后这个controller又收到了aop的管理,那么这个在controller中没有捕获处理的异常会先被aop捕获,然后这个时候问题就出现了!!!
aop中:
try {
//执行controller
result = point.proceed();
return result;
} catch (Throwable e) {
//抛出自定义的异常
}
filter中:
try {
//过滤
chain.doFilter(request, resp);
} catch (Exception e) {
// 返回json
response.setContentType("text/json; charset=utf-8");
PrintWriter pw = resp.getWriter();
pw.write(ResponseUtils.getFailResponseStr( e.getMessage()));
if (pw != null) {
pw.close();
}
return;
}
问题1:我在controller中没有处理的异常会到aop中被捕获进入catch (Throwable e),然后抛出一个自定义的异常,在外层的filter中被捕获进入 catch (Exception e) ,然后输出一下e.getMessage()。理论上是不是这样走一点问题都没有,但是实际上,返回给前端的是:java.lang.reflect.UndeclaredThrowableException
问题2:我在aop中抛出的异常会被捕获进入catch (Throwable e),然后抛出一个自定义的异常,在外层的filter中被捕获进入 catch (Exception e) ,然后输出一下e.getMessage()。理论上是不是这样走也没问题,但是实际上,返回给前端的又是:java.lang.reflect.UndeclaredThrowableException
个人觉得以上两种情况是不能接受的,前端完全不知道什么鬼,到底什么错都不清楚。。。
分析:aop中捕获的异常抛出去,其实并不是直接到filter,我猜测,我们在aop中抛出去的异常应该是被java动态代理处理异常的一个东西拦截了,据网上所说(可能不对,我没仔细研究过),一个异常是检查型异常并且没有在动态代理的借口处声明,那么它将会被包装成java.lang.reflect.UndeclaredThrowableException,之后应该是被springmvc中的NestedServletException捕获了,这个时候我们看到的异常就已经是java.lang.reflect.UndeclaredThrowableException了
解决:其实解决方法很简答,我们只要debug一下看看他有多少层,然后对应的去获取message就行了!
在拦截器中的catch里面加上这个代码即可:
String msg = null;
//如果是NestedServletException异常或者是他的子异常
if (e instanceof NestedServletException){
//获取内部异常
e = (Exception) ((NestedServletException) e).getRootCause();
if (e != null){
msg = e.getCause().getMessage();
}
} else {
msg = e.getMessage();
}
大部分人看到这个标签是不是会有疑问,不是应该是mybatis多值传参问题吗?不!单值传参也有你想不到的问题!
如果是多值传参,如果不使用@Param这个注解,在xml中直接用参数名字,很明显就会报错,但是如果单值传参不加这个注解也会报错:There is no getter for property named XXX 怎么说?你是不是很震惊!?
据我所知,好像是单值传参的情况下,如果在xml中有对这个参数做判断的话:
and AAA=#{XXX}
这个单值传参如果没有加注解就会报错,广大的mybatis使用者,可以去试一下!!!
CONCAT(pd.order_sn,'\t') as 订单号
这个问题本来早在前几期就想发出来的,但是一直没有研究明白。。。这个可以说是mysql的一个bug,也可以说是我经历的太少!
问题:查询一个结果集(根据某个字段降序),一条记录在不加limit的时候出现在92行,然后在sql之后加了一个limit 90,10之后,这条记录不见了?难道limit 90,10不是取第90~99条记录吗???
分析:个人猜想应该是order by之后的几个字段存在相同值太多,然后mysql也不知道到底要取那一条,如果刚好卡在分页的哪一环节,有可能一条记录会出现好几次,也可能会有记录查询不出来;
网上分析(个人觉得还行): https://www.cnblogs.com/glon/p/6806064.html
MySQL 使用 limit 进行分页时,如果排序字段有相同值的情况下,由于排序字段数据重复,可能会导致每次查询排序后结果顺序不同,分页还是会出现重复数据。
解决:
1、使用子查询:先不使用limit,先order by,然后在查出来的结果中使用limit - - - 个人觉得有点蠢。。。
2、再加一个排序字段,提高排序的唯一性,最好保证排序的字段在表中的值是唯一的,即id这种字段