SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇
SpringBoot基本原理,轻松应对面试官 - 第522篇
导读
一些小技巧在手,可以解决一些复杂的需求,所以一些小技巧平时自己也要多多总结,方能不乱于产品需求之中。
技巧一:获取项目全部URL
Spring boot 项目在做URL权限控制的时候需要获得全部的URL,一个一个去controller中找费时费力。而且有的权限点的命名和URL有一定的对应关系。如果能用程序获得全部URL,将会省去很多事。下面就介绍一种获取URL的方法。在项目中添加如下 Controller,请求 /getAllUrl,即可看到项目所有的URL。当然也可以根据项目将URL写入数据库或写入配置文件。
import com.kfit.common.annotation.Anonymous;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.util.*;@Controllerpublic class UrlController { @Autowired WebApplicationContext applicationContext; @GetMapping("/v1/getAllUrl") @ResponseBody public List<String> getAllUrl(){ RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); //获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<String> urlList = new ArrayList<>(); for (RequestMappingInfo info : map.keySet()){ //获取url的Set集合,一个方法可能对应多个url Set<String> patterns = info.getPatternsCondition().getPatterns(); for (String url : patterns){ urlList.add(url); } } return urlList; } @RequestMapping(value = "/v2/getAllUrl")@ResponseBody public Object getAllUrl2() { RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); // 获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<Map<String, String>> list = new ArrayList<>(); for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) { Map<String, String> map1 = new HashMap<>(); RequestMappingInfo info = m.getKey(); HandlerMethod method = m.getValue(); PatternsRequestCondition p = info.getPatternsCondition(); for (String url : p.getPatterns()) { map1.put("url", url); } map1.put("className", method.getMethod().getDeclaringClass().getName()); // 类名 map1.put("method", method.getMethod().getName()); // 方法名 RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition(); for (RequestMethod requestMethod : methodsCondition.getMethods()) { map1.put("type", requestMethod.toString()); } list.add(map1); } return list; }}
这里的提供了两种实现方式,访问:/v1/getAllUrl和/v2/getAllUrl进行查看:
/v1/getAllUrl:
/v2/getAllUrl:
技巧二: Thymeleaf 设置不校验 html 标签
默认配置下,Thymeleaf 对 .html 的内容要求很严格,比如<meta charset="UTF-8" />,如果少封闭符号/,就会报错而转到错误页。也比如你在使用 Vue.js 这样的库,然后有<div v-cloak></div>这样的 html 代码,也会被 Thymeleaf 认为不符合要求而抛出错误。
通过设置 Thymeleaf 模板可以解决这个问题,下面是具体的配置:
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
LEGACYHTML5 需要搭配一个额外的库 NekoHTML 才可用,项目中使用的构建工具是 Maven 添加如下的依赖即可完成:
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version></dependency>
技巧三:启用 Tomcat 的 MBean 注册表
嵌入式 Tomcat 的 MBean 注册表默认是禁用的。这最大限度地减少了 Tomcat 的内存占用。如果你想使用 Tomcat 的 MBeans,例如让 Micrometer 使用它们来公开度量指标,就必须使用 server.tomcat.mbeanregistry.enabled 属性来实现,如下例所示:
server: tomcat: mbeanregistry: enabled: true
开启以后,通过jconsole查看MBean信息,如下:
技巧四:默认AOP切面实现
通过BeanNameAutoProxyCreator可以对指定符合的类进行增强:
@Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator() { BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator(); beanNameAutoProxyCreator.setBeanNames("*Service") ; beanNameAutoProxyCreator.setInterceptorNames("tokenInterceptor"); return beanNameAutoProxyCreator ;}
上面的BeanNameAutoProxyCreator 是处理器类,只要beanName的后缀是Service结尾的都会被创建代理,然后通过以tokenInterceptor为beanName的拦截器增强。
技巧五:自动配置生效
每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项:
@ConditionalOnBean:当容器里有指定的bean的条件下。@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。@ConditionalOnClass:当类路径下有指定类的条件下。@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix="xxx.xxx", value="enable", matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。
使用这些条件注解在开发自定义组件的时候,能够很容易的实现一些开关和依赖关系的处理。
历史文章(文章累计520+)
Spring Boot整合ElasticSearch实战 - 第511篇
Transaction rolled back because it has been marked as - 第512篇
一文讲清楚SpringBoot项目打包jar后运行报错template might not exist - 第514篇
idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇
Noisee AI中文站网页版 AI 音乐生成视频全新登场,快来抢先体验------国内第一个登场的中文站来袭 - 516篇
Spring的SmartLifecycle可以没用过,但没听过就不好了!- 第517篇
SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇
SpringBoot基本原理,轻松应对面试官 - 第522篇
SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇
SpringBoot基本原理,轻松应对面试官 - 第522篇
导读
一些小技巧在手,可以解决一些复杂的需求,所以一些小技巧平时自己也要多多总结,方能不乱于产品需求之中。
技巧一:获取项目全部URL
Spring boot 项目在做URL权限控制的时候需要获得全部的URL,一个一个去controller中找费时费力。而且有的权限点的命名和URL有一定的对应关系。如果能用程序获得全部URL,将会省去很多事。下面就介绍一种获取URL的方法。在项目中添加如下 Controller,请求 /getAllUrl,即可看到项目所有的URL。当然也可以根据项目将URL写入数据库或写入配置文件。
import com.kfit.common.annotation.Anonymous;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.util.*;@Controllerpublic class UrlController { @Autowired WebApplicationContext applicationContext; @GetMapping("/v1/getAllUrl") @ResponseBody public List<String> getAllUrl(){ RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); //获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<String> urlList = new ArrayList<>(); for (RequestMappingInfo info : map.keySet()){ //获取url的Set集合,一个方法可能对应多个url Set<String> patterns = info.getPatternsCondition().getPatterns(); for (String url : patterns){ urlList.add(url); } } return urlList; } @RequestMapping(value = "/v2/getAllUrl")@ResponseBody public Object getAllUrl2() { RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); // 获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<Map<String, String>> list = new ArrayList<>(); for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) { Map<String, String> map1 = new HashMap<>(); RequestMappingInfo info = m.getKey(); HandlerMethod method = m.getValue(); PatternsRequestCondition p = info.getPatternsCondition(); for (String url : p.getPatterns()) { map1.put("url", url); } map1.put("className", method.getMethod().getDeclaringClass().getName()); // 类名 map1.put("method", method.getMethod().getName()); // 方法名 RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition(); for (RequestMethod requestMethod : methodsCondition.getMethods()) { map1.put("type", requestMethod.toString()); } list.add(map1); } return list; }}
这里的提供了两种实现方式,访问:/v1/getAllUrl和/v2/getAllUrl进行查看:
/v1/getAllUrl:
/v2/getAllUrl:
技巧二: Thymeleaf 设置不校验 html 标签
默认配置下,Thymeleaf 对 .html 的内容要求很严格,比如<meta charset="UTF-8" />,如果少封闭符号/,就会报错而转到错误页。也比如你在使用 Vue.js 这样的库,然后有<div v-cloak></div>这样的 html 代码,也会被 Thymeleaf 认为不符合要求而抛出错误。
通过设置 Thymeleaf 模板可以解决这个问题,下面是具体的配置:
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
LEGACYHTML5 需要搭配一个额外的库 NekoHTML 才可用,项目中使用的构建工具是 Maven 添加如下的依赖即可完成:
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version></dependency>
技巧三:启用 Tomcat 的 MBean 注册表
嵌入式 Tomcat 的 MBean 注册表默认是禁用的。这最大限度地减少了 Tomcat 的内存占用。如果你想使用 Tomcat 的 MBeans,例如让 Micrometer 使用它们来公开度量指标,就必须使用 server.tomcat.mbeanregistry.enabled 属性来实现,如下例所示:
server: tomcat: mbeanregistry: enabled: true
开启以后,通过jconsole查看MBean信息,如下:
技巧四:默认AOP切面实现
通过BeanNameAutoProxyCreator可以对指定符合的类进行增强:
@Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator() { BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator(); beanNameAutoProxyCreator.setBeanNames("*Service") ; beanNameAutoProxyCreator.setInterceptorNames("tokenInterceptor"); return beanNameAutoProxyCreator ;}
上面的BeanNameAutoProxyCreator 是处理器类,只要beanName的后缀是Service结尾的都会被创建代理,然后通过以tokenInterceptor为beanName的拦截器增强。
技巧五:自动配置生效
每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项:
@ConditionalOnBean:当容器里有指定的bean的条件下。@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。@ConditionalOnClass:当类路径下有指定类的条件下。@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix="xxx.xxx", value="enable", matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。
使用这些条件注解在开发自定义组件的时候,能够很容易的实现一些开关和依赖关系的处理。
历史文章(文章累计520+)
Spring Boot整合ElasticSearch实战 - 第511篇
Transaction rolled back because it has been marked as - 第512篇
一文讲清楚SpringBoot项目打包jar后运行报错template might not exist - 第514篇
idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇
Noisee AI中文站网页版 AI 音乐生成视频全新登场,快来抢先体验------国内第一个登场的中文站来袭 - 516篇
Spring的SmartLifecycle可以没用过,但没听过就不好了!- 第517篇
SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇
SpringBoot基本原理,轻松应对面试官 - 第522篇
SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇
SpringBoot基本原理,轻松应对面试官 - 第522篇
导读
一些小技巧在手,可以解决一些复杂的需求,所以一些小技巧平时自己也要多多总结,方能不乱于产品需求之中。
技巧一:获取项目全部URL
Spring boot 项目在做URL权限控制的时候需要获得全部的URL,一个一个去controller中找费时费力。而且有的权限点的命名和URL有一定的对应关系。如果能用程序获得全部URL,将会省去很多事。下面就介绍一种获取URL的方法。在项目中添加如下 Controller,请求 /getAllUrl,即可看到项目所有的URL。当然也可以根据项目将URL写入数据库或写入配置文件。
import com.kfit.common.annotation.Anonymous;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.util.*;@Controllerpublic class UrlController { @Autowired WebApplicationContext applicationContext; @GetMapping("/v1/getAllUrl") @ResponseBody public List<String> getAllUrl(){ RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); //获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<String> urlList = new ArrayList<>(); for (RequestMappingInfo info : map.keySet()){ //获取url的Set集合,一个方法可能对应多个url Set<String> patterns = info.getPatternsCondition().getPatterns(); for (String url : patterns){ urlList.add(url); } } return urlList; } @RequestMapping(value = "/v2/getAllUrl")@ResponseBody public Object getAllUrl2() { RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); // 获取url与类和方法的对应信息 Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); List<Map<String, String>> list = new ArrayList<>(); for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) { Map<String, String> map1 = new HashMap<>(); RequestMappingInfo info = m.getKey(); HandlerMethod method = m.getValue(); PatternsRequestCondition p = info.getPatternsCondition(); for (String url : p.getPatterns()) { map1.put("url", url); } map1.put("className", method.getMethod().getDeclaringClass().getName()); // 类名 map1.put("method", method.getMethod().getName()); // 方法名 RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition(); for (RequestMethod requestMethod : methodsCondition.getMethods()) { map1.put("type", requestMethod.toString()); } list.add(map1); } return list; }}
这里的提供了两种实现方式,访问:/v1/getAllUrl和/v2/getAllUrl进行查看:
/v1/getAllUrl:
/v2/getAllUrl:
技巧二: Thymeleaf 设置不校验 html 标签
默认配置下,Thymeleaf 对 .html 的内容要求很严格,比如<meta charset="UTF-8" />,如果少封闭符号/,就会报错而转到错误页。也比如你在使用 Vue.js 这样的库,然后有<div v-cloak></div>这样的 html 代码,也会被 Thymeleaf 认为不符合要求而抛出错误。
通过设置 Thymeleaf 模板可以解决这个问题,下面是具体的配置:
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
LEGACYHTML5 需要搭配一个额外的库 NekoHTML 才可用,项目中使用的构建工具是 Maven 添加如下的依赖即可完成:
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version></dependency>
技巧三:启用 Tomcat 的 MBean 注册表
嵌入式 Tomcat 的 MBean 注册表默认是禁用的。这最大限度地减少了 Tomcat 的内存占用。如果你想使用 Tomcat 的 MBeans,例如让 Micrometer 使用它们来公开度量指标,就必须使用 server.tomcat.mbeanregistry.enabled 属性来实现,如下例所示:
server: tomcat: mbeanregistry: enabled: true
开启以后,通过jconsole查看MBean信息,如下:
技巧四:默认AOP切面实现
通过BeanNameAutoProxyCreator可以对指定符合的类进行增强:
@Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator() { BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator(); beanNameAutoProxyCreator.setBeanNames("*Service") ; beanNameAutoProxyCreator.setInterceptorNames("tokenInterceptor"); return beanNameAutoProxyCreator ;}
上面的BeanNameAutoProxyCreator 是处理器类,只要beanName的后缀是Service结尾的都会被创建代理,然后通过以tokenInterceptor为beanName的拦截器增强。
技巧五:自动配置生效
每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项:
@ConditionalOnBean:当容器里有指定的bean的条件下。@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。@ConditionalOnClass:当类路径下有指定类的条件下。@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix="xxx.xxx", value="enable", matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。
使用这些条件注解在开发自定义组件的时候,能够很容易的实现一些开关和依赖关系的处理。
历史文章(文章累计520+)
Spring Boot整合ElasticSearch实战 - 第511篇
Transaction rolled back because it has been marked as - 第512篇
一文讲清楚SpringBoot项目打包jar后运行报错template might not exist - 第514篇
idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇
Noisee AI中文站网页版 AI 音乐生成视频全新登场,快来抢先体验------国内第一个登场的中文站来袭 - 516篇
Spring的SmartLifecycle可以没用过,但没听过就不好了!- 第517篇
SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇
SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇
SpringBoot开发的AI导航站技术架构剖析 ------ 技术如何选型 - 第520篇
SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 -- 一不小心就会写出一个重大BUG!!- 521篇