一致照应体处置器详解-Spring-Boot
在SpringBoot运行中,一致处置照应体是一项十分关键的义务,它可以让咱们更繁难地一致规范API的前往格局。当天,咱们将深化讨论一个优雅的处置打算——经常使用ResultHandlerAdvice,经过它成功一致照应体的增强处置。
背景
在实践名目中,咱们经常会面临API前往的一致格局要求,而不同的Controller或者前往不同类型的数据。为了处置这个疑问,咱们可以经常使用SpringBoot的ControllerAdvice和ResponseBodyAdvice来成功全局的照应体处置。
成功
首先,让咱们看一下如何经过代码成功这个处置器。以下是一个繁难的例子:
importlombok.extern.slf4j.Slf4j;importorg.springframework.core.MethodParameter;importorg.springframework.http.MediaType;importorg.springframework.http.server.ServerHttpRequest;importorg.springframework.http.server.ServerHttpResponse;importorg.springframework.web.bind.annotation.ControllerAdvice;importorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/***一致照应体增强处置器*/@ControllerAdvice(basePackages="com.example.controller")@Slf4jpublicclassResultHandlerAdviceimplementsResponseBodyAdvice{@Overridepublicbooleansupports(MethodParameterreturnType,ClassconverterType){log.info("returnType:"+returnType);log.info("converterType:"+converterType);returntrue;}@OverridepublicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){if(MediaType.LICATION_JSON.equals(selectedContentType)){//判别照应的Content-Type为JSON格局的bodyif(bodyinstanceofResult){//假设照应前往的对象为一致照应体,则间接前往bodyreturnbody;}else{//只要反常前往的结果才会进入这个判别流程,所以前往反常成功的形态码Resultresult=Result.buildSuccessResult(body);returnresult;}}//非JSON格局body间接前往即可returnbody;}}
运行
经常使用这个处置器后,一切被@ControllerAdvice注解标注的Controller都将遭到影响。这象征着,无论哪个Controller前往的数据,都会经过咱们定义的处置逻辑,确保照应的一致性。
@RestController@RequestMapping("/api")publicclassMyController{@GetMapping("/data")publicMyDatagetData(){//实践业务逻辑...returnnewMyData("Hello,World!");}}
MyDataResult
总结
经过ResultHandlerAdvice,咱们成功了一个繁难而有效的全局照应体处置器,确保了API的一致照应格局。这样的设计不只提高了代码的可保养性,还使得团队开发中更容易达成一致规范,优化了名目标全体品质。宿愿这篇文章对你了解和经常使用SpringBoot中的全局照应体处置有所协助!
Spring Boot 开发工具的使用
Spring Boot 提供了一套额外的工具,可以提升应用程序开发的体验,只用在项目中包含spring-boot-devtools模块就行。该模块会在开发模式下设置一些默认的属性,例如:禁用缓存、设置日志等级;还会监听 classpath 的变化,自动的重启应用。spring-boot-devtools给开发带来了很多的便利,这篇文章总结可它的一些用法。
要使用 devtools,需要先添加模块依赖,Maven 和 Gradle 的配置如下:
运行完整打包的应用时,开发工具会被禁用。当使用java -jar或者特殊的类加载器运行时,会被认为是生产环境。在 Maven 中使用<optional>true</optional>标记该依赖时可选的,或者在 Gradle 中使用自定义的developmentOnly配置可以防止开发工具应用到项目的其他模块。
Spring Boot 中的一些库会通过缓存来提升性能。比如:模块引擎缓存已编译的模板,已避免重复解析模板文件;Spring MVC 在响应静态资源时设置 HTTP 缓存头。 启用缓存在开发环境中非常有用,但是在生产环境下却适得其反。因此spring-boot-devtools默认会为我们禁用掉缓存,而不用再去手动禁用了。 同时,开发工具还会将 Web 日志的等级设置为DEBUG ,这样就可以看到更加详细的请求和响应信息。如果要记录所有请求详细信息(包括可能的敏感信息),可以启用-request-details 。 如果不想使用默认的配置,可以设置-properties为false 。
当 classpath 上的文件发生修改时,使用了spring-boot-devtools的应用会自动重启。在开发过程中,会是一个有用的功能,因为可以快速地看到修改导致的变化。 由于 DevTools 监视 classpath 资源,因此触发重新启动的唯一方法是更新 classpath。在 Eclipse 中,默认在修改文件并保存时会自动编译,从而触发 classpath 更新,而 IntelliJ 中需要手动构建项目( Build -> Build Project )才行。当然,IntelliJ 中也可以 设置自动编译 ,但我觉得没有必要。
Devtools 通过两个类加载器来完成重启,对于第三方库等不会发生修改的类,使用base类加载器,用户编辑的类则使用restart类加载器。当应用重启时, restart类加载器会被丢弃然后创建一个新的,这样会加快重启的速度。如果觉得重启不够快,可以考虑使用JRebel ,它通过重新载入类来实现热更新。
默认情况下,每次应用程序重新启动时,都会输出条件评估增量的报告。该报告显示了修改应用程序时自动配置的变化,例如:添加或删除 Bean 以及配置属性。
添加下面的配置可以关闭该日志:
某些资源在更改时不需要触发重启。默认情况下, /META-INF/maven 、 /META-INF/resources 、 /resources ,/static 、 /public或/templates中的资源发生修改时不会触发重启(但是会触发 live reload,见下文)。 如果想要自定义需要排除的目录,可以通过属性配置(逗号分隔多个)。如果想要维持默认的配置额外的排除其他目录,可以通过-exclude属性配置。
通过-paths可以配置额外的路径以监听变化。
如果不想使用重启功能,可以通过属性设置。大多数情况下,直接在中设置即可。如果想要完全禁用重启,需要在调用(…)之前设置 System属性为false :
如果使用不断编译已更改文件的 IDE,可能更喜欢仅在特定时间触发重新启动。我们可以使用“触发器文件”,这是一个特殊文件,当想要实际触发重新启动检查时必须修改该文件。更改文件只会触发检查,只有在 Devtools 检测到必须执行某些操作时才会重新启动。触发器文件可以手动更新,也可以使用 IDE 插件更新。 将-file属性设为触发文件路径。
spring-boot-devtools 模块包含一个嵌入式 LiveReload 服务器,可用于在资源更改时触发浏览器刷新。浏览器需要安装LiveReload 插件 。
如果不想启用 LiveReload 服务器,设置属性为false 。
一次只能运行一个 LiveReload 服务器。如果从 IDE 启动多个应用程序,则只有第一个具有 LiveReload 功能。
在$HOME目录下创建一个文件,在里面添加全局的 devtools 设置。添加到此文件的任何属性都会应用到本机所有使用 devtools 的 Spring Boot 应用程序中。
04《Spring Boot 入门教程》使用模板引擎开发 Web 项目
模板引擎这个词,咋听起来,有点高大上的意味。
实际上,模板引擎是非常平易近人的技术。譬如大家可能都比较熟悉的 JSP ,就是一种比较典型的模板引擎。
当浏览器将请求抛给控制器,控制器处理好数据后,就跳转 JSP 等模板引擎页面。注意在跳转的同时,还会将数据组装好,也交给模板引擎处理。
模板引擎会根据数据,和模板引擎的规则,动态生成 HTML 页面,最后返回给浏览器显示。
我们使用 Spring Boot 开发 Web 项目,大体上有两种方式。
第一种方式,是后端服务化的方式,也是当前的主流方式。前端是静态的 HTML 页面,通过 Ajax 请求 Spring Boot 的后端接口。 Spring Boot 返回数据一般采用 JSON 格式,前端接收后将数据显示。
第二种方式,是采取模板引擎的方式。前端的请求,到达 Spring Boot 的控制器后,控制器处理请求,然后将返回数据交给模板引擎。模板引擎负责根据数据生成 HTML 页面,最后将 HTML 返回给浏览器。
我个人比较推荐第一种方式,说一下该方式的几个优点:
本篇是讲模板引擎,也得说说模板引擎的优点,王婆卖瓜不能光夸草莓啊。模板引擎开发的页面,对搜索引擎 SEO 比较友好;还有就是简单的页面,如果用模板引擎开发速度比较快,毕竟模板化的方法,目的就是减少重复提高效率。
Spring Boot 支持的模板引擎种类很多,常见的有 FreeMarker 、 Thymeleaf 、 JSP 。
因为这些模板引擎使用的用户都不少,所以我们逐一介绍下其实现过程。
至于孰优孰劣,请各位看官自行评价。正所谓:尺有所短,寸有所长,各取所爱,万物生长!
本篇我们开发一个商品浏览项目实例。
此处说一个我个人的经验:在做一个项目或一个模块的时候,不要一开始就动手写代码,最好是谋定而后动。
我们作为程序员,实际上是整个程序世界的总指挥。应该先整体规划,再实现局部。这种总分型的开发方法便于我们理顺思路,提高编码效率!
好的,我们来思考下,实现商品浏览项目实例的整体流程:
整体流程
可以看到,我们是先建立了控制器方法和页面,再去实现其中的具体细节。这样可以让我们的思维保持连贯性和整体性,在做一些页面和方法较多的项目时,会感觉更加顺畅。
我们按整体流程,使用 FreeMarker 模板引擎,来实现商品浏览功能。
使用 Spring Initializr 创建项目,Spring Boot 版本选择 2.2.5 , Group 为, Artifact 为spring-boot-freemarker,生成项目后导入 Eclipse 开发环境。
引入 Web 项目及 FreeMarker 模板相关的依赖项,代码如下:
实例:
创建控制器类,由于是商品相关的控制器,所以命名为 GoodsController ,代码如下:
实例:
我们具体解释下该类的作用。
我们resource/templates目录下新建商品页面,先不必实现具体功能,代码如下:
实例:
此时我们启动项目,然后访问,即可显示对应页面内容。
定义商品类 GoodsDo 用来描述商品信息,注意 Do 表示数据模型对象(Data Object),代码如下:
实例:
然后我们编写服务类 GoodsService ,提供获取商品列表的方法。注意此处仅仅是展示模板引擎,并不需要访问数据库,直接返回一个指定内容的商品列表。
实例:
此时,我们的控制器就可以注入 GoodsService 类型的组件,然后调用其方法了。
实例:
注意(goodsList, ());,我们将商品列表相关的数据交给模板引擎去处理。
此时我们可以根据 FreeMarker 模板引擎,按模板规则显示商品信息了。
实例:
注意我们通过 FreeMarker 的模板语法,输出了商品列表信息。关于 FreeMarker 模板引擎更多的语法规则,感兴趣的同学可以后续查阅更多资料。
启动项目,打开浏览器访问,即可查看输出结果。
Thymeleaf 和 FreeMarker ,都是模板引擎,使用方法基本类似。此处我们仅仅是给出一个范例,不再做过多的解释。
使用 Spring Initializr 创建项目, Spring Boot 版本选择 2.2.5 , Group 为, Artifact 为spring-boot-thymeleaf,生成项目后导入 Eclipse 开发环境。
引入 Web 项目及 Thymeleaf 模板相关的依赖项。
实例:
创建控制器类, GoodsController , Thymeleaf 直接使用 HTML 作为模板页面,故代码如下:
实例:
我们在resource/templates目录下新建商品页面,先不必实现具体功能,代码如下:
实例:
此时我们启动项目,然后访问,即可显示对应页面内容。
商品类 GoodsDo ,服务类 GoodsService ,这两个类与上面没有区别直接放出代码。
实例:
实例:
好的,此时我们的控制器就可以注入 GoodsService 类型的组件,然后调用其方法了。
实例:
此时我们可以根据 Thymeleaf 模板引擎,按模板规则显示商品信息了。
实例:
注意我们通过 Thymeleaf 的模板语法,输出了商品列表信息。关于 Thymeleaf 模板引擎更多的语法规则,感兴趣的同学可以后续查阅更多资料。
启动项目,打开浏览器访问,即可查看输出结果。
到此,大家基本上也能发现,这两种方式除了模板页面文件内容不同,其他地方基本都是一模一样的。
也就是说,模板引擎主要负责通过一些模板标签,将控制器返回的数据解析为网页。
注意 Spring Boot 官方已经不推荐使用 JSP 了,确实操作起来也比较麻烦。但是由于 JSP 用户体量还是比较大的,所以此处还是简单展示下,开发步骤与 FreeMarker / Thymeleaf 基本一致。
使用 Spring Initializr 创建项目, Spring Boot 版本选择 2.2.5 , Group 为, Artifact 为spring-boot-jsp,生成项目后导入 Eclipse 开发环境。
引入 Web 项目及 JSP 模板相关的依赖项。
实例:
创建控制器类, GoodsController ,代码如下:
实例:
手工添加src/main/webapp及子目录如下,同时目录下放一个 用于测试。注意该目录是一个 Source Folder 源代码目录,不是普通文件夹目录。
spring-boot-jsp 项目结构
实例:
注意,我们还需要添加一个视图解析器,实现 JSP 页面往指定目录跳转。
实例:
此时我们启动项目,然后访问,即可显示对应页面内容。
商品类 GoodsDo ,服务类 GoodsService ,这两个类与上面没有区别直接放出代码。
实例:
实例:
好的,此时我们的控制器就可以注入 GoodsService 类型的组件,然后调用其方法了。
实例:
此时我们可以根据 JSP 模板引擎,按模板规则显示商品信息了。
实例:
注意我们通过 JSP 的模板语法,输出了商品列表信息。关于 JSP 模板引擎更多的语法规则,感兴趣的同学可以后续查阅更多资料。
启动项目,打开浏览器访问,即可查看输出结果。
最后大家应该也发现了, FreeMarker 和 Thymeleaf 的用法几乎是一模一样的,而 JSP 还需要手工添加一些目录和配置。
三种方式各有优劣, FreeMarker 模板语法比较简洁, Thymeleaf 可以直接使用 HTML 作为模板文件, JSP 用户群体广泛。
但是三种方式,都是一种模板引擎而已,将控制器返回数据转化为 HTML 页面显示,本质上没啥区别,大家对模板引擎有一个了解即可。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。