SpringBoot Web篇笔记(一)
摘要
文章是根据江南一点雨(松哥)的视频进行总结
全局异常处理
通常情况下,我们都需要对自己定义的异常进行相应的处理。捕获指定的异常方式如下:
@controlleradvice public class exceptionhandlers { // 捕获自定义异常类进行处理 @exceptionhandler(customexception.class) public modelandview handler(customexception e) { modelandview modelandview = new modelandview("customexception"); //自定义异常错误页面 modelandview.addobject("msg", e.getmessage()); // ... return modelandview; } }
自定义错误页面
若服务器抛出404错误码(页面找不到)时,通常会返回如下页面:
而我们需要指定在服务器抛出相应的错误码时,跳转到指定的动态或静态页面。
源码阅读
参考默认的视图解析器org.springframework.boot.autoconfigure.web.servlet.error.defaulterrorviewresolver
源码,取出部分代码片段如下:
public class defaulterrorviewresolver implements errorviewresolver, ordered { private static final map<series, string> series_views; // 存放不同错误码对应的视图 // 添加默认的视图 static { map<series, string> views = new enummap<>(series.class); views.put(series.client_error, "4xx"); views.put(series.server_error, "5xx"); series_views = collections.unmodifiablemap(views); } ... // 开始解析错误视图 @override public modelandview resolveerrorview(httpservletrequest request, httpstatus status, map<string, object> model) { // status.value() 得到的是错误码 // 寻找错误码指定的页面,如404就找名为404的页面 modelandview modelandview = resolve(string.valueof(status.value()), model); // 若找不到错误码指定的页面,则400,401,403,404...都会去找4xx的页面 if (modelandview == null && series_views.containskey(status.series())) { modelandview = resolve(series_views.get(status.series()), model); } // 若modelandview还是null,那么就返回上面的那个图片了 return modelandview; } private modelandview resolve(string viewname, map<string, object> model) { string errorviewname = "error/" + viewname; //首先去动态资源中查看是否存在对应的页面 templateavailabilityprovider provider = this.templateavailabilityproviders.getprovider(errorviewname, this.applicationcontext); if (provider != null) { return new modelandview(errorviewname, model); } //若动态资源中找不到则到静态资源中寻找对应的页面 return resolveresource(errorviewname, model); } //获取静态页面资源 private modelandview resolveresource(string viewname, map<string, object> model) { // 遍历静态资源,查找是否有对应的页面 for (string location : this.resourceproperties.getstaticlocations()) { try { resource resource = this.applicationcontext.getresource(location); resource = resource.createrelative(viewname + ".html"); if (resource.exists()) { return new modelandview(new htmlresourceview(resource), model); } } catch (exception ex) { } } return null; } ... }
阅读源码总结
1.首先会去找指定错误码的页面,若指定页面找不到则找4xx、5xx页面,(400、401...都会找4xx)
2.先到动态资源下的error目录寻找,再到静态资源中的error目录寻找
实现
如果为动态资源的页面,返回的modelattribute可以查看org.springframework.boot.web.servlet.error.defaulterrorattributes
, 返回的数据如下:
timestamp
status
error
message
...
thymeleaf
下页面使用如下:
<table> <tr> <td th:text="${status}"></td> </tr> <tr> <td th:text="${message}"></td> </tr> </table>
若需要扩展,则继承defaulterrorattributes
,对扩展类加@component
注释:
@component public class customerrorattribute extends defaulterrorattributes { // 扩展 }
cors跨域
在前后端分离进行开发的情况下,一般都需要设置跨域访问,springboot提供cors
跨域设置如下:
@configuration public class webmvcconfig implements webmvcconfigurer { @override public void addcorsmappings(corsregistry registry) { registry.addmapping("/**") //所有前缀 .allowedorigins("http://localhost:8081") //跨域地址(前端地址) .allowedheaders("*") //允许所有请求头 .allowedmethods("*") //允许通过所有方法 .maxage(30 * 1000); //探测请求的有效期 } }
注册拦截器
拦截器可以拦截request
请求,若自定义权限认证的功能,就可以使用拦截器去进行实现。
public class myinterceptor implements handlerinterceptor { @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { return false; } public void posthandle ... public void aftercompletion ... }
prehandler
执行方法前调用,posthandler
在返回视图前调用,aftercompletion
在方法执行完后调用。
添加拦截器到配置中,重写addinterceptors
方法
@configuration public class webmvcconfig implements webmvcconfigurer { @override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(myinterceptor()) .addpathpatterns("/**"); //拦截所有路径 } @bean myinterceptor myinterceptor() { return new myinterceptor(); } }
整合servlet
首先自定义的servelt继承javax.servlet.http.httpservlet
;使用@webservlet
进行url映射
@webservlet(urlpatterns = "/myservlet") public class myservlet extends httpservlet { @override protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception { system.out.println("doget"); } }
在启动类xxxapplication
对自定义的servlet的目录进行扫描
@servletcomponentscan(basepackages = "org.java.servlet")
这就可以成功访问到啦!localhost:8080/myservlet
扩展(怕忘记了,记一下):request
监听实现接口javax.servlet.servletrequestlistener
, 然后对request
监听类使用javax.servlet.annotation.weblistener
注解;request
拦截器实现接口javax.servlet.filter
,然后对拦截器使用javax.servlet.annotation.webfilter
注解,如:
@weblistener public class myrequestlistener implements servletrequestlistener { @override public void requestdestroyed(servletrequestevent sre) {system.out.println("requestdestroyed");} @override public void requestinitialized(servletrequestevent sre) {system.out.println("requestinitialized");} } @webfilter(urlpatterns = "/*") //对所有目录进行拦截 public class myfilter implements filter { @override public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception { system.out.println("dofilter"); chain.dofilter(request,response); } }
上述的监听器和拦截器一定要在@servletcomponentscan
的扫描目录下或子目录。
若文章有错误或疑问,可在下方评论,thanks♪(・ω・)ノ。
上一篇: 鸡蛋吃多了会胖吗?鸡蛋有哪些吃法
推荐阅读
-
ecshop调用文章显示上一篇下一篇_html/css_WEB-ITnose
-
HTML DOM(学习笔记一)_html/css_WEB-ITnose
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用
-
SpringBoot中并发定时任务的实现、动态定时任务的实现(看这一篇就够了)推荐
-
详解SpringBoot中异步请求和异步调用(看完这一篇就够了)
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用
-
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
-
C#Web应用程序入门经典学习笔记之一
-
SpringBoot中并发定时任务的实现、动态定时任务的实现(看这一篇就够了)
-
WebGL学习教程之Three.js学习笔记(第一篇)