00:00
好,前面呢,我们分析源码,看了一下spring boot底层默认的异常处理的整个流程,以它的原理,那接下来我们看一下我们如何定制我们的错误处理逻辑,而定制错误处理逻辑呢,我们大概总结有这么多种方式,首先来看第一种方式,我们可以自定义错误页,这在官方文档里边有说的,我们只需要给error这个文件夹下放一些五叉叉或者404页面就行,但是呢,我们会后来分析原理的时候,我们发现这块的功能是由这个default error view reserve它来完成的,而这个default error view reserve来CTRV它里边的核心来解析错误视图的时候,它是用了这么一个方法来拿到你的这个错误的状态码,相当于如果是404或者500,他呢,先来看你的这个状态码的Y6精确值,相当于他先去你的下边找有没有一个精确的404页面,如果找到了就有你的,如果没有找到,他就用他的status的series,也就说它里边的这一个。
01:00
系列码,所有的系列码呢,点进来其实就是这些五开头的五叉叉,所以呢,我们现在呢,看到的一个这样的效果,就是如果我们来做一个示范假设呢,我们这个请求还要一个int a的这个参数,我们让它发送请求的时候就来传递过来request来看一下,如果是这种情况下,它是出现一个什么样的错误,如果我们不传这个A,或者传的这个A不是一个int类型的参数。来看他怎么办。因为呢404它只能匹配我们页面找不到,而我们客户端传的这个请求参数如果是错误,它其实就是一个四百四百的这个状态嘛,来看看能不能定位到我们的默认错误页,我们可以来登录进来测试一下,123456走。来看一下,我们来点它,哎,我们发现呢,又回到了一个默认的白页,这个白页的状态码呢是400,那原因呢,是我们需要的这个参数A是不存在的,所以呢,我们就会发现一件事情,我们这一块呢,它会默认给我们来找精确匹配,就是有精确的这个错误状态嘛,对应的页面就按照精确页面,如果没有才找你这些什么叉叉之类的页面,所以呢,我们可能为了适配我们客户端更多的错误,比如有400,有404,我们可以shift f6,我们给这呢,把这个404改成四叉叉,所以呢,注意这一块的错误呢,如果不带请求参数,不带请求参数就是400,不带请求参数,或者咱们这个参数类型不对,那都是400错误,400呢叫band request,叫错误的请求,对吧,Band request一般呢,都是都是我们这个浏览器传的参数不对,都是浏览器的参数没有传递。
02:48
正确,所以呢,我们一般排错的时候呢,看到400,你就看客户端发的这个请求参数对不对,那我们这个400呢,原来是默认跳不到这个页面的,我现在来把这个页面呢,改成四叉叉以后来看一下能不能调到。
03:06
我们在这来做一个测试,回车需要重新登录,走好,我们来看到我们点一个它,诶我发现呢,我们也找,我们相当于呢也跳到这儿了,但是呢,跳到这儿呢,我希望它在这打印,打印呢,我们这个页面到底是什么错误状态码,以及错误原因,那要不然都是404看起来啊不对,所以呢,我们在这来打印一下,我们来th test th test,我们在H2这呢,我们来打印一个错误状态嘛,那么现在都知道所有的错误内容都在我们的error attributes里边,它呢,其中就有一项叫status,这个status里边呢,有我们的错误状态嘛,啊在这个里边呢,暂时没有,那我们可以达到错误状态嘛,我们也可以达到这个错误的消息,TH,我们的test,那这个错误的内容是什么?我们可以打它的message,好,然后呢们来把这个页面CTRLF9啊重新编译一下,我们再来刷新。
04:07
来看一下啊,这个错误呢,其实就是400,而我们真正的没有找到的请求走,那它呢就是404,所以呢统一呢都跳到了我们这个四叉叉页面,那这就是呢,我们通过分析源码,我们找到的一个细节,这是我们说的第一种我们的错误处理方式,这已经没问题了,接下来我们来看第二种错误处理方式,我们为了处理一些错误呢,我们可以使用controller advice加exception handler的方式,可以来处理全局异全局异常,那这种呢,也是我们使用spring m VC里边经常用的方式,好,我们来给大家演示一下,我现在先来准备上一个包,这个包呢就是exception包,提前创建好,来专门来写一个类,这个类呢就来处理我们整个系统的这个异常,比如我们聚焦global global的我们的这个exception handle,我们全局的这个异常处理器,它的这个作用呢,就是我么处理,处理整个MVC里边的异常,处理整个咱们这个web的异常。
05:07
所以呢,我们接下来在这外表的什么异常呢?Controller的异常啊,Controller的异常,然后呢,我们需要呢,标注一个注解叫controller advice controller advice呢,点进来我们发现它呢,其实也是一个component,而且呢,它最终会被增强,那这个component呢,相当于自动就把它放在容器中了,所以我们接下来只要需要写一个方法,因为我们现在看到啊,我们的这个方法里边可能不止这个方法会出现错误,可能其他的方法呢,都会出现错误,所以呢,我们随便来准备上一个方法,我们让他来处理错误就行了,我们来返回spring,哎,我们就来处理处理,比如我们来专门处理数学运算异常的ari,我们的这些异常的exception,所以呢,那接下来我们就可以给这个方法上来写上啊这样一个注解叫exception handle了,但exception handler呢,就代表我们当前呢是一个异常处理器,它来专门来处理异常。但是处理。
06:07
什么样的异常我们可以说清楚,那们在这个exception handle里边,我们专门来指定它来处理哪些异常来点进来,它呢有一个叫value,它呢是可以写一个数组,现在能处理多个异常,比如那我们就在这儿来写一个数组,我们能处理数学运算异常,这是异种,然后呢,比如我还处理控制针异常,这呢是一种,那相当于呢,我们这个方法就能接受这两种异常,然后我们接下来给他来在这儿处理,处理完了以后呢,我们返回一个值,这个值是什么,这个值呢,相当于我们前面的方法处了异常以后,那我由我们这个函导的最终处理,因为我们都知道,我们分析源码的时候,即使是异常处理,异常处理呢,最终返回的都是一个model and view,哎,整个异常处理完了以后呢,返回一个model and view,所以呢,我们相当于返回的这个东西还是一个视图地址,当然我们也可以直接在这返回model and view,那这样。
07:07
这样的话呢,我们相当于返回到这个数据,既包含视图,又包含我们这个模型数据,所以呢,我为了简单,我可以直接返回一个视图地址,比如我们返回哪个地址呢?我就来返回log页,那它的这个前缀啊后缀这都有了,这返回log页,所以呢,这是我们的这个异常包括的异常信息我们想要获取,比如我们想在这啊打印记录一下异常,到底我们捕获到了系统的什么异常,我们可以在这日志记录一下log.l来记录一下异常,我们这个异常是是什么呢?我们把这个异常打印一下,那怎么获取我捕获到的异常,我们可以给方法参数位置写一个exception,那这样呢,它捕获到的哪个方法的异常会被自动封装到这个里边,那么只需要打印它就行了,好,这是我们自己己写的,专门来处理全局异常的这个CTRL来做一个测试,看一下我们发生异常以后能不能。
08:00
跳到我们指定的这个logn页,那接下来我们来做一个测试,走,我们先来进行登录,123456,好,登录进来,我们先来看第一种,我点它,诶为什么没到log梗页,它是响应400,原因在这,我们的这个异常只能处理数学运算异常和空指针异常,它呢并不能处理,相当于我们的这个叫啊,我们这一块大家看啊,它在这打印了一个叫Miss s request private,它缺少S参数的这个异常,所以呢,我们并不能处理这个异常,那我们想要呢,让它真正的能进入到我们的处理逻辑,我就给他给一个A等于一,那么参数就传对了,将来数学运算走好,数学运算错了,来到logo页没问题。那这就说明我们这个全局的异常处理它是没问题了,那它的原理是什么样的呢?我们可以来重新debug看一遍,把这个所有的断点呢,我们都放开,主要呢,我们给dispa of来打上了断点以及目标方法,来看一下它在这一块是怎么成功的跳到这个logo页来回车,好,现在来进入到我们的请求,先来确认我们当前请求basic table没问题,然后呢,接下来来一步一步放行,我就直接来放行到这一块来执行目标方法,好放行到这目标方法执行呢,因为有错,这个错误呢会被这一块来进行看直掉,然后呢,在下边是我们来处理要跳转页面的过程,所以我就直接来放行,放行呢,它在这执行目标方法,我们来放行完,放行完以后呢,我们看目标方法出现错误,叫数学运算异常,来到我们这一块来进行处理,页面跳转,把这个数学运算异常传进去,因为目标方法出错了,所以没有返回model and view step进行two进来,然后呢,一旦出错以后呢,他该怎么解析,那就来到。
09:51
这我们这个异常呢,因为有了我们是数学运算异常,它调用我们的这个process handle exception来处理异常,怎么处理呢?Step to,那还是我们以前的逻辑,把所有的异常解析器拿来进行挨个遍利尝试来看啊。第一个异常解析器,这个叫default error attributes,它呢解析出来,我们以前知道它默认行为只是把错误呢存储到request域中,然后直接返回为空,所以呢,相当于它不能解析,因为它返回的是空,只有不等于空的时候才算成功,所以呢它没有解析,然后呢,接下来是第二个,第二个呢,因为它的这个reserve是所有这个异常解析器的一个组合,所以我们还得携带to进来,这个进来呢,其实跟前面的写法一样,还是遍利所有的这个异常解析器来看谁能解析,所以接下来呢,就会遍利到第一个异常解析器,所以大家一定注意,那么现在呢,这有默认的三个异常解析器,其实现在呢,听这个名字我们就知道是啥意思了,这三个异常解析器呢?
10:51
我们之前截过图,第一个叫exception handler exception receiver,它呢就是专门来解析,如果目标方法出异常了,来看有没有标了exception handle的注解,能处理这个异常,如果能处理就调用目标方法来进行处理,所以这一块呢,如果想要解析step into进来,那它整个的这个流程,那都是来找,看我们哪个标了哪哪个方法标了exception handle了,那就是这个方法标了exception handle了,而且能处理数学运算异常,所以呢它就处理了,那我们来step into进来,所以我们会看到,哎,没有step into,我是来直接放行,直接放行呢,它就直接来到我们全局的异常处理器里边来进行处理,那它是怎么找到exception handle来的,这就是系统一启动加载,通过分析每一个注解,这个注解能处理啥运算异常,提前缓存过来而已,好,那接下来呢,会返回一个return一个什么值,Return一个string字符串,但是大家注意我们return的这个string字符串,我们现在呢全部结束这个方法呢,就被。
11:51
当成一个非常正常的方法,我们来看一下啊,包括呢,你return的也应该是一个model and view,它被当成一个非常正常的方法,所以呢,我们现在呢,返回的这个数据呢,是一个我们要去登录页model里边没啥数据的,所以呢我们相当于第一个exception handle了,就能解析了,因为它呢是专门专门处理except看到了注解的,所以呢第一个解析成功,有了model and view,有了model and view,那把这个异常呢一记录它LOG1记录,将来把这个RESULT1返回,像我们现在呢,就有了一个model and view,第一个异常解析器处理成功,能返回一个model and view给我们最终返回出去,然后这不为空,然后break返回出去,然后呢,最终我们判断了这个model and view里边呢是不为空的,而且有视图信息的啊,把这个返回出去,那最终呢,像异常处理会返回一个model and view u没问题,然后呢,接下来在这判断model and view不为空吗?其实这个model and view u就是异常处理器那个类的方法给我返回到model and view u。
12:51
要去log页,所以接下来又进入渲染流程,那去log页该怎么去就怎么去,所以呢,我们通过分析源码,我们发现了这个我们的这种方式其实就是调用人家底层的这个叫exception handler,你叫exception,一个exception handler exception reserve就是来调用它来进行处理的control home,它呢是专门来处理我们exception handler该注解的,包括我们这个方法的这个注释,这一块呢也说的很清楚。
13:24
它呢是专门来处理except,不是看看到了标注的这些方法,好把这个拿过来,所以呢,它的底层原理是用它,它的底层是它提供了这个处理支持,是它支持的好,那第一种呢,错误方式,那我们就过了,我们以后呢也推荐,其实我们在以后的开发我们也推荐呢,是使用我们这种方式,剩下的这个静态页就直接给它放行出去啊,那这是我们的第一种异常处理的方式,第二种异常处理的方式呢,我们也可以这样,我们比如在某一次发请求的时候,有可能会抛出一些我们自己的异常,比如我们在这来做一个简单的,呃,简单判断吧,那么在这来只也不说简单判断,我来判断一个这个东西来判断一个,判断一个什么呢?如果我们的这个a list这个user里边点Les,如果它的这个L,它。
14:25
它的S大于大于三,相当于它里边呢有三个元素,那我们就给它抛一个异常,这异常呢就是有太多用户的异常,所以我们还可以有一种异常处理行为,就是我们使用response letters加自定义异常的方式,那么现在呢,准备一个自定义异常,因为我们后来系统里边有非常多的异常,它是来自定义异常,比如我们就叫user to many。哎,User在太多的这个异常,用户太多的异常,然后呢,我们就让他来继常,他呢能抛出去,那就是一个运行时异常啊,然后呢,我们来写上它的这个有参构造器啊,我们来比如来user to many exception,把它这个有参构造器呢给它加上。
15:16
Public,而且这个异常呢,你也可以带一个信息,比如这个mecy,我们只给它给一个有参构造器,然后呢,这个有参构造器里边我们可以这么来写super,我们把这个message呢,就传到我们真正的这个异常里边,好,这个异常呢,我却给它标注这么一个注解叫response status,然后呢,Response step的意思就是哎,我们这个异常呢,最终可以给你返回一个状态码信息,这状态码信息呢,我们可以来在这来指定这一块呢,其中呢就有一个叫VALUE6,它能指定我们这个状态码,如果发生这个异常,给页面给什么样的HTP状态码,这个状态码呢,比如我们就叫啊,比如我们就叫有一个我们http steps来错误的请求吧,比如就叫forbid拒绝403,这就是一个403状态嘛,我们就用它,然后呢,接下来错误的原因我们也可以在这指定,对吧,原因呢,就是啊用户数量太多数量。
16:17
太多。这个异常呢,你也可以给一个自定义的这个错误消息,把这个有参无参可以都加上啊,然后呢,这是我们来准备的一个异常,那么有可能呢,是这么来做的,我来就来抛出一个用户太多异常,User to many exception,然后呢,我们把这个异常抛出去,这个异常抛出去以后呢,我们先来看效果,我把这个项目呢重新启动,我们不以debug模式,如果我们来访问这个请求,来看我们出现这个异常的情况下,它给我们响应什么页面,因为我们这个异常上呢,标了一个注解叫response status。来,可以看一下,走来先来登录进来。
17:05
我们来到这个高级页面叫呃,动态的这个页,然后呢,我们会看,诶给我们来响应了这么一个页,叫403用户数量太多,诶这个数量太多的原因就是我们在这给自定义异常标了一个response status注解,所以呢,哎,我们就出现了这个页面,那我们再来看一下这个自定义异常它又是怎么解析到我们这一块的内容的,为什么他能把response status里面的FORBID403和用户数量太多拿出来放在我们这个页面,好,那么现在呢,再以debug模式启动起来。这个呢也是一种错误的,我们的异常处理的方式,我们先来禁用掉所有我们把整个流程呢再走一遍回撤好,我们先要登录123456先登录进来。好,我们准备要去这个动态页,我们把这个断点呢给大家打开。
18:04
来看这种我们来点进来,好,现在请求进来,请求进来呢,现在我们的请求,诶这个怎么是image来给它放行,诶好,那就是这个动态的胎报请求,这个动态的胎报请求呢,我们现在来到这动态的胎报请求没问题吧,好在这呢,他转转没问题,然后我们来看,然后呢,目标方法想要来进行执行,当然我们这个目标方法执行呢,由于会出异常,你就来直接放行,放行到这我们来捕获一下这个异常,这异常呢,就是我们自定义的异常,应该没啥问题,我们来看一下这个异常,将user to many exception来看它怎么解析这个异常,Step into进来,然后呢,来到我们的这个异常处理的流程,在这来进行异常处理,Step into进来,还是我们之前的流程,遍利所有的异常解析器来解析,第一个异常解析器默认的default error attribute,啥活不用干,我们就直接给它放行。第二个呢,由于它是组合的异常解析器,它里边组合了三个,我们刚测了一个叫exception handler,下来我们来测,大家来看啊,第二个。
19:05
专门叫response status,那它其实就是处理response status注解这种方式的自定义异常逻辑的,那step用图进来来看一下啊,所有的reserve,第一个reserve,现在exception handler肯定解析不了了,因为我们exception handler解析不了自定义异常,我们在这呢,只给他说了这两个异常数学运算和空指针,所以呢,我们这一块我们也不用进去了啊,直接返回为空好不能处理,不能处理呢,接下来来到第二个异常解析器叫response status,它怎么解析step into进来好,我们会发现它先判断能不能解析,能不能解析呢,进来进来呢,他他的这一块判断,我们就直接给他放行,他这一块呢肯定是可以的,然后呢,接下来来看啊,他来在这准备解析,来做我们的这个解析流程,做解析流程呢,Step into进来,他呢就来判断exception,我们的这个异常是不是response statuss这个异常,也就说你的异常呢,也可以继承于它。
20:05
我们来看一下啊,但是呢,我们是自定义的,不是接下来呢,它判断用a not工具类,相当于我们这个注解工具类,看我们当前的这个异常user to many这个异常有没有标注response letters注解,巧了,我们正好标注了,所以呢,相当于它就找到了这个注解,找到这个注解以后呢,那接下来他就把这个注解的信息解析出来,返回一个model and view,所以呢,其实底层的支持,我们这个注解呢,底层的支持就是它啊异常处理的我们说的自定义的第二种方式,他的底层是他来支持的,而他整个支持的逻辑呢,很简单,那其实就是把我们这个response letters注解的信息拿来组装成注解的信息,组装成model and返回就行了,And view返回好,那组装成model and view。
21:05
它自然呢,我们来看一下啊,它组最终组装的这个model and view是把注解的这个状态码,这个状态码呢拿到,还有把注解的这个错误原因拿到,然后呢把它应用进去,所谓的这个应用就是呢,用了一个model and view,而且呢,大家注意啊,我们的这个错误原因这个都有了,它在这还会response send error相直接跳取一个错误页,这个错误页呢就是403,所以呢我们会看啊response status这个注解它呢会调用send error方法。它的底层,底层调用SLSL呢,相当于就直接结束了,直接结束了这个送L呢,相当于给to姆K发了一个错误叫,而这个L呢,其实就相当于映射到我们最终底层的这个杠L了,这就是我们以前说的所谓的这个杠L,底层的我们能进入到的这个杠L,没人没人能处理这个错误,它会进入到杠L,或者我们调用response send的L。
22:12
因为这个杠L呢,也是Tom k给我们来发的,所以这个sin的底层调用,它其实呢,就是Tom KT处理的处理的杠error,他们send的error就是Tom k发送的杠error,而Tom k发送的杠error呢,Spring mvc又能发送的杠error,而大家一定要注意你的请求呢,一旦1RESPONSE送的error,这次请求就结束了,我们来看啊,请求就结束了,Model and view呢都是空的,这个请求结束了呢,我们来看一下我们的这个效果,Model and view好,他最终给我们返回的这个model and view model and view呢有对象,但是没有什么页面,所以呢,我们把这一块拿到达到,所以呢,我们相当于第二个异常解析器能处理了response status专门是来组装,我专门是来解析我们这个response status注解的,它呢,呃,它倒不是把它组装成modern段的U返回modern段,它呢是直接把这个注解的信息拿来。
23:12
然后呢,调用send error,现在直接呢告诉他们get,你给我发error请求,请求的错误信息就是这个错误状态码是他,错误信息是他,而一发这个error请求,那最终相当于好我们这个model and VR,大家看啥都是空的,然后呢就是所有的异常解析器最终便利,其实最终呢得到的这个Mo端view都是空的,都是空的,那就是进入到我们好之前的这个流程,相当于任何解析器都没有人能解析,但实际上呢,它解析了。他解析了,只不过呢,他直接是送的L了,所以呢,这次请求之后,我们来直接一放行会他CA会收到一个L请求,再来发给我们spring m VC底层,然后呢,就进入到我们下边的error处理逻辑,我们的error页面,最终给我们来适配到我们的四叉叉,五叉叉这些页面,所以呢,这是我们说的response status response status呢,它会直接send l,好没问题,这是我们说的第二种异常处理的类型,还有第三种,还有一种异常处理呢。
24:20
就是我们框架底层工作的一些异常,比如我们spring来进行数据类型转换啦,我们参数不存在啦等等这些,来举个例子,还是我们的这个页面,我们这个basic table,如比如就是这个异常,如果我们当前这个A,它的这个参数不存在,来看一下它是怎么样被处理到的,我们把这个断点呢都放开,还是我们的这些断点。因为首先我们参数不存在这个异常,来确认一下全局异常处理不了没问题,然后呢,它也不是我们自定义异常要response that注解的,然后呢,他我们来看一下他怎么处理回车请求进来,那来确定basic table没问题进来,首先来第一个请求来到这请求来真正要执行,执行出错把这个异常记录下来,这个异常呢是我们叫missing s,大家注意啊,因为这个异常呢是框架自己抛的,你看前面的这个包名,它都是框架的异常,这个框架呢,他说我们当前参数A不存在,来看这种异常它是怎么被处理的,Stepb图进来,来到我们的异常处理,因为我们现在有异常了,进入异常处理逻辑,然后呢,又是所有的异常解析器,异常解析器里边第一个default error attributes,啥活没干,继续放行,然后呢,第二个我们的,因为它是一个组合的异常解析器,所以得step into进来,然后呢,接下来它遍历所有的这个异常解析器,这个所有异常解析器。
25:43
这有三个,第一个叫exception handler,现在我们来听名字,Exception handler肯定不行,Response status,它处理response boths status注解的,它是处理exception handler注解的,所以这两个呢,都不行,都不行呢,我们就接下来我们这个都不行啊,接下来来到第三个,所以接下来看第三个异常解析器,叫default handle exception reserve,它是干嘛的,Step into它的解析异常呢?还是来直接进入它的do resolve方法step into它呢,非常简单,判断我们这个异常呢,是不是HTTP叫request method not support请求方式不支持的异常,是不是这个媒体类型不支持的常,是不是我们这种各种其他的异常,其中就有一个叫missing sole request para异常,那么当前的这个异常音呢?
26:32
确认一下就叫missing,那么缺少请求参数的,所以呢,相当于它在这啊,它是我们的这个异常处理器,它的作用呢,就是处理spring MC底层的异常,就是它,它呢来处理我们框架底层的异常,这些异常呢,你在这个类里边就能发现有多少呢,我就不一一列举了,自己进这个类里边,然后这异常处理的逻辑是什么,我们就来进来看一下啊,那么当前呢,是solid的这个异常,好,我们来step into,进来step into,那看它怎么处理的,继续是干嘛叫send error,大家一定注意,那send error的作用就是此次请求立即结束,然后呢,他们看的服务器底层再给他们再转出一个error error谁能处理就谁处理,处理不了Tom k就会响应Tom k最原生的那个错误页,我记得应该是一个蓝白的这些页,所以呢,Tom KT也有原生的错页。
27:32
所以呢,它在这呢,也是response send l来我们来看一下啊,Tom k原生的错误页,我们来给大家搜一下吧,看网上有没有这个图,他们错误页错误页。对,就是这样子的图。哎,就是这么样的一个图,所以呢,To cat呢,有可能也有它原生的错误件,但我们呢,肯定不能用它,这个呢有点丑,而我们呢,现在这个错误件呢,就是只要你一次L最终呢肯定就会来到这个错误页,但这个错误页呢,如果我们什么都不处理,那就是他们开头默认的错误页,就是这个长长得挺丑的,而们现在呢,Spring mvc底层专门有人处理这个L,那就是我们专门有人在下边匹配杠L请求就是什么呢?看一下啊,就是我们后来分析原理的default error attributes,就是它它它呢啊,我们这个底层还配了一个叫basic error controlrler,就是这个error controlrler,它专门来处理杠error,所以他们看的底层最终的杠errorr会被它来处理,它呢又利用错误的视图解析器,我么响应我们自定义的几叉插页,所以呢,即使我们在这里编写原生方法的时候,比如我们这拿到了一个response,哎,我们发现呢,请求处理一半不行了,我们自己。
28:52
到L也会来到我们的这个几插插件,所以呢就会很方便,这是我们说的这种方式,比如说呢,底层的一些异常是由它来处理的,所以至此呢,你会发现我们把默认的这几个异常处理器,哎,都给大家是不是解析清楚了,也就是它是专门来处理exception handle来注解的,它是专门来处理response letter注解的,它是专门来处理default handler啊,它是专门来处理我们spring这个框架底层异常的,当然所有的这些异常这个解析器它们呢,都是都是这个东西,我们来看一下啊,他们呢都是这个接口。
29:34
都是来到上边将handler exception reserver,所以呢,如果你对默认的这些异常解析器你不满意,咱也可以自定义异常解析器,所以来到这我们也可以自定义一个叫customer customer,我们的这个handler exception reserver,我们自定义的异常解析器,自定义的异常解析器呢,我们自然就要实现我们自定义的,呃,实现我们的这个接口,那这个接口呢,我们来看一下啊,自定义的异常解析器,那自定义的异常解析器呢,我们只需要按咱们这个component把它放在容器中,然后呢,我们会看到这专门有一个方法让我们自己来解析异常,这个解析异常呢,其中就是这。
30:20
拿到这个异常类型,然后呢,接下来我们你也可以返回model and view这个页面,当然我们可以在这我们也学人家的写法,你可以返回一个model and view,如果你的这个model and view里边有视图地址有什么,那自然跳到你的视图地址,如果没有,我们也可以写我们的这种方式叫send error,好,我们呢,直接给他们开一个错误,这个错误是多少呢?我们自己来写一个状态码,比如五叉叉,我写个511对吧,然后呢,这个状态码就是我喜欢的错误,而且呢,因为我们自己写的这些错误排发它呢也会被干嘛,也会被我们的五叉叉页面所处理,而五叉页面呢,也会取出我们的message信息,我们可以不妨来看一下啊,我们的这个五叉叉,我们的在这个,在这个在下边,我们不取,在这个下边吧,在这个下边,那th test我们就来给取出。
31:21
我们当前的错误状态码到底是多少?好来重新启动起来。所以呢,我们也可以使用自定义的异常解析器,来看我们自定义的异常解析器能不能工作。我们这些自定义的异常解析器呢,能处理我们的这个异常,然后呢,到底能处理哪些异常,那问题就来了,所以我们现在呢,以得bug的方式先进来。我们现在来随便发一个异常,看一下我们自定义的这个异常解析器啥时候来进行工作。好,Debug进来呢,我们先把所有断点禁掉,没问题,我先登录进来。
32:04
走123456走起,然后我们来注意,我们随便点一个都会有异常,我现在把这个断点放开看一下啊。断点放开,然后呢,我们来刷新,我们来点一下它,好,我们现在来发送的是basic table这个请求,这个请求呢,我们让它执行左起好执行,执行呢,目标方法出异常,这个异常呢,是我们的这个什么异常,我们来看一下啊,这个呢是我们这个参数不存在的异常,这个参数不存在异常,我们来step into进来,来看它咋处理,来到我们所有的异常解析流程,Step into,然后呢,它遍历所有的异常解析器,大家注意现在这个异常解析器里边有三个了,而三个呢,其中就有一个我们的异常解析器,大家想啊,我们的这个异常解析器现在能不能生效呢?不能,因为我们可以来看一下我们的这个异常解析器,而第一个异常解析器,我们返回的model and view是那的第二个异常解析器,是组合的异常解析器,它尝试我们这三种异常解析能不能相当系统自带这三种能不能解析,而我们的这个参数不存在异常。
33:18
正好是人家默认的异常,像人家默认异常能解析,所以人家默认异常直接返回了一个model and view这个对象,所以呢,都没有轮到我们第三个异常解析器,所以呢,我们想要让我们自定义的异常解析器生效,那得咋办?这个呢,全部放心啊,因为我们会看到呢,我们自定义的异常解析器它的在它在最后一个,所以我们只需要给这加一个注解叫O的,好,我们可以给它指定一个顺序,这个顺序呢,我们可以让它有最高优先级,比如这一个VALUE6默认呢,它是最低优先级的,我们可以让它有一个有一个order的这个接口,我们让它拥有最高优先级,好,那这样最高优先级其实就是我们说的这个啊,Int的最小值,数字越小,优先级越高,你也可以给这随便给一个数字,哎,一定给一个这优先级数字,数字越小,那这个优先级。
34:18
越高,好,那我们现在呢,如果是这种方式的情况下,来重新启动,看我们自己定义的这个异常解析器,它能不能最先工作。一旦我们自定义了异常解析器以后,来看一下效果啊,我们还是来禁掉所有的这个断点,好,我们先来到登录页再说,因为我们所有的东西都要登录。123456,诶我们来登录错误了,123456走来我们来点一个bic table看一下啊,我们把这个断点打开,点一个basic table,走先来到我们这个方法目标方法执行出现异常,好我们准备要处理step图进来,进来以后呢,我们来到它的这个整个异常处理流程,Step图进来看一下所有的这个异常解析器有多少个啊来现在所有的异常解析器将下来都要遍利我们的这个异常解析器,大家看,我们终于把它的顺序调到第一位了,第一位的话,那就调用我们的解析异常方法。四在北京图进来,好,我们呢,直接是送L,然后返回一个model and view,大家注意,因为我们返回model and view这个对象了,所以呢,轮不到别人解析了,其实我们这个对象里边啥都没写,所以呢,我们在这儿直接一放行,最终看到的这个效果,锻炼一境全放行完,那就是这样子的,来来到我们这。
35:47
二我喜欢的错误511,也就是说呢,我们现在最终哎,我们写了一个自定义异常处理器,而这个异常处理器呢,我们最终把这一块呢,给大家再拿过来,还是发一个请求,要说其实有它以后,它的这个优先级就最高了,走回车,因为我们当前呢,相当于能解析所有异常,好我们在这儿来看一下所有的异常解析器,我们所有的异常解析器呢,我们的就排在优先原则了。
36:22
走,所以呢,相当于我们的全局异常处理也没用了,User to many的这个response status其实也没用了,因为都是我们处理的,所以呢,相当于你以后呢,出现了任何异常,直接都是我喜欢的异常,你不妨可以来试一下啊,任何异常这是basic table,人家呢,还有一个高级的叫我的万s table,应该是他吧,看一下啊,哎,这是一个404,呃,这个这个404,嗯,不,这个不算啊,我们来之前的这个处理是啥嘞?好,这是我喜欢的异常,那现在来到我们的这个慢页面吧,好,这个呢,由于是用户太多,哎,我们发现它也成了语言我喜欢的错误,包括呢,我们数学运算异常也成了我喜欢的错误,那数学运算呢,只要我们来传对参数,让它方法进去,都是数学运算,都成了我喜欢的错误。原因就是因为我们自定义的。
37:23
异常处理器优先级别特别高,所以他说是什么就是什么,所以呢,这是我们说的这种方式,自定义异常处理,你呢可以把它的优先级调高,让他也作为默认的全局异常处理规则,可以作为全局异常处理规则。这个呢,就是我们说的,我们如果想要自定义异常处理,就是我们这些逻辑,那最终有一个逻辑呢,就叫I view reserve,这个呢我们一般不去自定义,为什么呢?因为我们发现了系统底层的一个逻辑,只要我们以response send l相当于tomcat,底层只要一感受到使用这种方式要跳转页面。
38:09
只要1RESPONSE send的error,这个error请求呢,就会error请求,Error请求就会转给controller,就会转给controller,没有两种方式,转给ctrler,第一个你明显的调用送的LL转给ctrler,第二个你的异常没有任何人处理,也会直接送的L转给ctrler,那异常没有任何人能处理,人能处理,相当所有人都返回到mode端,又都是那的异常解析器返回的都是那的,没有任何人能处理,也是交给tomca了,也是tomcat底层S。没任何人都不能处理,也是底层性能,Error相当于还是呢,传递给我们的这个ctrler,俺们这个controltrler呢,最终要去哪个error是由这个error view receive解析的,而error view receive的规则,而我们的这个controltrler,这个controltrl呢叫basic error ctrler,它要去什么页?
39:09
他要去这个error页,但是这个页呢,具体的地址是由我们的这个will receive来进行解析的,是由它解析的。所以呢,他要去的页面地址,页面地址是他解析的,而他解析的规则呢,就是拼上我们的这个状态码信息,除非呢,你不想去你这个规定的error下的叉叉叉这些页了,你可以定义它的这些规则比就说呢,他相当于是最底层的一个异常处理,所有的异常都最终能被他捕获,只要没人处理的异常都能被他捕获啊,这是我们所有说的整个异常处理的所有逻辑,大家不妨在下边画图,整个呢串一下。
我来说两句