springboot 1.5.6 返回html页面失效_Spring Boot学习04_自适应定制错误数据原理

在我们访问Spring Boot应用的时候,出现譬如404,500的错误,默认会跳到如下页面

e7039ddccf23fcf59093189575bfa89e.png

而做服务端的,浏览器并非为唯一客户端,还有安卓客户端app显示错误数据的方式,如下:(使用postman工具模拟安卓客户端app接受请求),Spring Boot会响应给安卓客户端json数据

40dbb319a9609212eefa7e186c139a92.png

这样的页面终归是不友好的,一般会自己定制页面或定制json数据(符合项目风格的错误页面)


前面的文章说了Spring Boot的自动配置一般都会在xxxAutoConfiguration类中

错误页面的自动配置在ErrorMvcAutoConfiguration类中

1、该类中有个errorPageCustomizer方法,返回的类型是ErrorPageCustomizer(错误页面定制器),只要项目中出现4xx或者5xx错误就会执行该方法。

7b2bf407c559ad6b6f77ea10b00af16a.png

2、我们点进ErrorPageCustomizer类中查看registerErrorPages方法,而该方法呢会发送一个getPath()请求,最终获得是@Value("${error.path:/error}"),意思是从配置文件中获取error.path的值,如果没有就使用"/error"请求url

80d60d72ae3dad1aaea6cd8d5bfef8cf.png

e328e8b6fa4d95716750976fb0ebd9b5.png

5ea3cc50afe5da705a708510829a94f7.png

3、只要请求"/error",那么在ErrorMvcAutoConfigutaion类中注册的BasicErrorController就会起作用了。

9bd29da3e53a247d299444a9ebe614f0.png

4、点进该类中查看发现该类就是映射"/error"请求的

7074bba7c59b472929a9f9fa9c7ae6f1.png

5、该类中有两个方法errorHtml方法返回ModelAndView,这两个方法都能接收"/error"请求,error方法返回ResponseEntity也就是json数据,说明这两个方法对应的就是浏览器和客户端,errorHtml方法上的produces等于"text/html",就是响应html类型的数据,而在浏览器中优先接受的就是该类型,客户端优先接受的是application/json类型,所以Spring Boot就能自适应返回不同的数据了

bf83931f71b2f8d3f4df2b1f964b99e6.png

67497d7f237b2419cf2ab82bd0684afb.png

19798b016056a4980870d4b963544996.png

一、浏览器怎么定制错误页面(errorHtml方法)

1、进入resolveErrorView方法,点进去

this.resolveErrorView(request, response, status, model);

-->resolver.resolveErrorView(request, status, model);

进入到ErrorViewResolver接口,该接口只有一个实现类,进入DefaultErrorViewResolver类中的resolveErrorView方法(DefaultErrorViewResolver也是在ErrorMvcAutoConfiguration类中进行注册了的)

c22852189a6970604b58a82e6796252f.png

59259cca040c71550ee615c49a4e8bb7.png

c8d27cf73feb1a3da72ddb7dc6d31b72.png

0096b6380a09cfc37d360a98b5ff7b0e.png

2、resolveErrorView方法会调用resolve方法,会传入状态码和model(后面解释怎么来的)进去,SERIES_VIEWS中有4xx,5xx

7b14bd1b2c8e327ed489bd588f07b7f5.png

08b9e17078aad947231233840982707e.png

3、进入到resolve方法,里面会拼一个视图名称"error/" 加上传进来的状态码(4xx,5xx),

这里会根据你的错误类型是什么就会拼成什么类型的视图名称。接着看下面有个方法判断有没有使用模板,如果使用了模板就直接把拼好的视图名称当作逻辑视图名称创建ModelAndView对象返回(使用了Thymeleaf模板,会有一个Thymeleaf视图解析器:前缀是classpath:templates/,后缀是html),如果没有就调用下面resolveResource方法

888d764c8394a7a7350f210aec388aea.png

4、进入resolveResource方法里面的逻辑就是获得静态资源映射的路径(专栏前面的文章有详细讲过(链接)),然后跟传过来的视图名称拼起来并加上html后缀

7ea5626efdc8e63e0ed5a4651ecd187f.png

5、最后说明我们只要把4xx,5xx命名html错误页面放在error文件夹下,然后把error文件夹放入templates文件夹下Spring Boot就会根据是什么类型的错误而跳转到指定的错误页面中。静态资源文件夹下的错误页面就不测试了,一定也是有用的

9e0506d54b982524caa247b8408c0733.png

da7691f02c7681f96b177965583c7a14.png

6、之前Spring Boot默认的错误处理页面中的数据是怎么获得的呢

回到errorHtml方法,点进getErrorAttributes方法

protected Map<String, Object> getErrorAttributes(HttpServletRequest request,

boolean includeStackTrace)

-->return this.errorAttributes.getErrorAttributes(webRequest,

includeStackTrace);

this.errorAttributes就是ErrorAttributes接口类型的,该类只有一个实现类DefaultErrorAttributes(在ErrorMvcAutoConfiguration类中在容器中注册了)

b26e35a7ef4b8e747f84d69d73fada32.png

5526180a7f246672412a7b78d757337e.png

5375939b3eca5d406f0c213d1bb160a4.png

7b9204f826f3802dc77f180eef07573d.png

6.1、看getErrorAttributes方法中会创建一个Map,而下面的方法处理就是往该map中添加一些错误数据,比如status状态码,error错误提示信息,exception异常类型。添加完成之后将该Map返回作为model

d66294ddf7c6dc464cc88e00d8c89880.png

e9c4cf51f49f50b298516577919e34b8.png

6.2、所以我们在模板里面就能通过表达式取到错误信息了,异常必须在全局配置中设置项目中包含异常server.error.include-exception=true

8db9be32d27fade5b9f82a04225f5da3.png

18147eb770e4cb12348ba3de79766350.png

7、Spring Boot默认的页面是怎么组成的呢

如果ModelAndView为空(说明自己在规定的路径中没有自定义错误页面)就自己创建一个ModelAndView,然后返回

584b1d301673cb60ae2c0f028222f4d1.png

7.1、在ErrorMvcAutoConfiguraion类中配置了一个组件name就是error,点进defaultErrorView(StaticView类型)

871cfb313f3be7024ff072ad1bbed446.png

7.2、该类中有个视图渲染方法,就是一个组装好的html字符串和之前Spring Boot默认处理错误页面中的信息一样。

a9fdb155f18a03c7fdb7f97fb17d0403.png

二、客户端怎么定制错误数据(error方法)

1、error方法中获取Map数据也是和上面一样的逻辑,最后转换成一个json数据返回给安卓客户端

3c4cb2635f5804b7dc31eca6dec435d7.png

2、之前说了哪个数据的获得其实是在容器中获取一个ErrorAttributes类型的实例然后调用该实例的getErrorAttributes方法,而ErrorAttributes类型的实例又是在ErrorMvcAutoConfiguration中进行了配置。

106dbf87dcf084cc7df264e104ac494a.png

3、ErrorMvcAutoConfiguration中配置ErrorAttributes的方法上面有@ConditionalOnMissingBean,意思是容器中没有ErrorAttributes这个类型我就自动配置,那我们就可以写一个DefaultErrorAttributes的子类并重写getErrorAttributes方法,然后添加到容器中。这样的话上面Spring Boot的自动配置ErrorAttributes就不会生效,到时候调用getErrorAttributes方法就会调用我们自己重写的方法,以达到我们定制异常数据的效果。

4dfce7d29e9a672510038a8a2cb6ff4c.png

4、我们这里调用父类的方法,先把Spring Boot默认可以获得到的数据先拿到,然后自己可以添加一些额外的数据并返回,最终获得到的model就是我们这个map,浏览器和客户端的数据都是在这获得到的。

c876e2b0b9c0d7222f9597b4ddaf7c17.png

124487eb5dfb1f8d040e0a075d19112d.png

5、如果项目中要处理对应的异常类型但是我们又要兼顾Spring Boot的自适应异常处理,在Spring MVC中我们就已经学习了自定义异常处理。这时候我们只需要根据Spring MVC的来做,最终我们请求转发到 "/error"请求,就会由BasicErrorController来处理自适应。最终又会执行到我们重写的getErrorAttributes方法中,我们自定义的异常信息就能放到request域中,在重写的getErrorAttributes中取出来放到map中,在前端就能取到自定义的错误值了。

cf1826e3ef4ad6b427c5d2c783cfe929.png

9bd839e0691f35a43070bcf46b947202.png

总结:在ErrorMvcAutoConfiguration类中自动重要的四个组件

1、DefaultErrorAttributes:封装异常数据的,getErrorAttributes方法

2、BasicErrorController:处理异常请求的,映射error请求,进行自适应处理

3、ErrorPageCustomizer:错误页面定制器,出现了4xx,5xx的错误就会执行该类中的

registerErrorPages方法,然后发送error请求

4、DefaultErrorViewResolver:异常视图解析器,resolveErrorView方法根据是什么类型

的异常就解析成什么视图名称

970cc73ccc2838512e8ac6d52adbf0c5.png

dd30fde3c3f6c3d78e62f7ce9db50fb8.png

1、在error文件夹下创建4xx,5xx为名的html后缀的页面,用到了模板就把error文件夹放入templates文件夹。没有用到模板就放到静态资源映射路径文件夹下。项目出现了错误,Spring Boot就可以找到对应的页面。

2、页面中可以通过模板中的表达式取到错误信息,也可以通过重写方法配合自定义异常处理器来定制错误信息

<!-- 状态码 -->
<h1>status:[[${status}]]</h1>
<!-- 时间 -->
<h3>time:[[${#dates.format(timestamp, 'yyyy-MM-dd HH:mm:ss')}]]</h3>
<!-- 错误提示 -->
<h3>error:[[${error}]]</h3>
<!-- 异常信息 -->
<h3>message:[[${message}]]</h3>
<!-- 异常对象 -->
<h3>exception:[[${exception}]]</h3>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要启动一个继承了SpringBootServletInitializer的Spring Boot 1.5.6项目,你需要按照以下步骤进行操作: 1. 确保你的项目已经正确配置了Spring Boot 1.5.6版本的依赖。 2. 打开你的主应用程序类(通常是带有@SpringBootApplication注解的类),确保它继承了SpringBootServletInitializer类,就像这样: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.support.SpringBootServletInitializer; @SpringBootApplication public class YourApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 3. 确保在你的项目中有一个war包的构建配置(pom.xml文件),以便将项目打包成war包,而不是默认的jar包。在pom.xml文件中添加以下配置: ```xml <packaging>war</packaging> ``` 4. 最后,使用Maven或Gradle等构建工具构建项目,并生成war包。 对于Maven用户,可以运行以下命令构建项目: ``` mvn clean package ``` 对于Gradle用户,可以运行以下命令构建项目: ``` gradle clean build ``` 5. 构建成功后,你可以将生成的war包部署到支持Java Web应用程序的服务器(如Tomcat),并启动服务器。 注意:确保你的服务器已经正确配置,并且支持部署war包。 一旦服务器启动成功,你的Spring Boot应用程序就会被自动启动,并可以通过服务器的URL访问。 希望这些步骤对你有所帮助!如果有任何疑问,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值