当前位置: 首页 > news >正文

手机做免费个人网站做网站找哪家好

手机做免费个人网站,做网站找哪家好,做界面的网站,做企业网站需要资质吗【SpringBootStarter】 目的 了解SpringBoot Starter相关概念以及开发流程实现自定义SpringBoot Starter(全局加解密)了解测试流程优化 最终引用的效果&#xff1a; <dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring…

【SpringBootStarter】

目的

  1. 了解SpringBoot Starter相关概念以及开发流程
  2. 实现自定义SpringBoot Starter(全局加解密)
  3. 了解测试流程
  4. 优化

最终引用的效果:

<dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>

【开源地址】https://gitee.com/xbhog/encry-adecry-spring-boot-starter;欢迎star

了解SpringBoot Starter相关概念以及开发流程

SpringBoot Starter

SpringBoot Starter作用将一组相关的依赖打包,简化项目的配置和初始化过程,通过特定的Starter开发者可以快速的实现特定功能模块的开发和扩展。

自定义Starter能够促进团队内部资源的复用,保持项目间的一致性,提升协作效率并且有助于构建稳定、高效的大型系统。

开发流程

注入SpringBoot的方式

在刚开始开发Starter的时候,首先考虑的是怎么能注入到SpringBoot中

这部分涉及到部分SpringBoot的自动装配原理,不太清楚的朋友可以补习下;

注入SpringBoot需要配置文件,在项目中的resources资源目录中创建该目录和文件。

demo-spring-boot-starter
└── src└── main└── java└── com.xbhog├── DemoBean.java└── DemoBeanConfig.java└── resources└── META-INF└── spring.factories

spring.factories中我们指定一下自动装配的配置类,格式如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xbhog.DemoBeanConfig
/*** @author xbhog* @describe:*/
@Slf4j
@Configuration
public class DemoBeanConfig {@Beanpublic DemoBean getDemo() {log.info("已经触发了配置类,正在初始化DemoBean...");return new DemoBean();}
}
@Slf4j
public class DemoBean {public void getDemo(){log.info("方法调用成功");}
}

这样就可以将设置的包扫描路径下的相关操作打包到SpringBoot 中。

SpringBoot主类启动器:初始化的操作,感兴趣的朋友可以研究下

完成后,我们可以打包该项目,然后在测试工程红进行Maven的引入、测试。

测试

新建Spring 测试工程,引入依赖:

<dependency><groupId>com.xbhog</groupId><artifactId>demo-spring-boot-starter</artifactId><version>1.0</version>
</dependency>
@RestController
public class BasicController implements ApplicationContextAware {private ApplicationContext applicationContext;/**两种引入方式都可以@Autowiredprivate DemoBean demoBean;*/@GetMapping("/configTest")public void configTest() {DemoBean demoBean = applicationContext.getBean(DemoBean.class);demoBean.getDemo();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

请求地址后,可以观察控制台,如下日志表示SpringBoot Starter可以使用了。

到此,一个简单的Starter开发完成了,后续可以围绕工程,根据需求和业务,对通用功能(接口操作日志、异常、加解密、白名单等)进行封装,最后打到Maven仓库中进行使用。

自定义SpringBoot Starter(全局加解密)

来源

在之前金融系统开发中,需要对接多个第三方的服务且数据安全性要求比较高;在接口评审阶段需要双方在数据传输的时候进行接口加解密;起初在第一个服务对接的时候,将相关的加解密操作写到工具类中;随着后续服务的增多,代码的侵入越来越严重。

封装

选择通过Starter进行功能的封装;好处:引用方便,开发迭代方便,团队复用度高且对业务没有侵入。

开发

思路:通过配置文件初始化,让配置类注解@ComponentScan扫描到的Bean等注入到SpringBoot中,通过自定义注解和``RequestBodyAdvice/ResponseBodyAdvice组合拦截请求,在BeforBodyRead/beforeBodyWrite`中进行数据的前置处理,解密后映射到接口接收的字段或对象。

接口上的操作有两种方式:

  1. 注解+AOP实现
  2. 注解+RequestBodyAdvice/ResponseBodyAdvice

这里我选择的第二种的RequestBodyAdvice/ResponseBodyAdvice,抛砖引玉一下。

**【注】**第二种存在的局限性是:只能针对POST请求中的Body数据处理,无法针对GET请求进行处理。

项目结构:

encryAdecry-spring-boot-starter
└── src└── main└── java└── com.xbhog├── advice│   ├──ResponseBodyEncryptAdvice.java│   └──RequestBodyDecryptAdvice.java├── annotation│   └──SecuritySupport├── handler│    ├──impl│    │   └──SecurityHandlerImpl.java│    └──SecurityHandler└── holder│    ├──ContextHolder.java│    ├──EncryAdecryHolder.java│    └──SpringContextHolder.java└──GlobalConfig.java└── resources└── META-INF└── spring.factories

项目处理流程图:

核心代码:

@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {log.info("进入【RequestBodyDecryptAdvice】beforeBodyRead的操作,方法:{}",parameter.getMethod());SecuritySupport securitySupport = parameter.getMethodAnnotation(SecuritySupport.class);assert securitySupport != null;ContextHolder.setCryptHolder(securitySupport.securityHandler());String original = IOUtils.toString(inputMessage.getBody(), Charset.defaultCharset());//todolog.info("该流水已插入当前请求流水表");String handler = securitySupport.securityHandler();String plainText = original;if(StringUtils.isNotBlank(handler)){SecurityHandler securityHandler = SpringContextHolder.getBean(handler, SecurityHandler.class);plainText = securityHandler.decrypt(original);}return new MappingJacksonInputMessage(IOUtils.toInputStream(plainText, Charset.defaultCharset()), inputMessage.getHeaders());
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {log.info("进入【ResponseBodyEncryptAdvice】beforeBodyWrite的操作,方法:{}",returnType.getMethod());String cryptHandler = ContextHolder.getCryptHandler();SecurityHandler securityHandler = SpringContextHolder.getBean(cryptHandler, SecurityHandler.class);assert body != null;return securityHandler.encrypt(body.toString());
}

Starter中的全局加解密默认采用的国密非对称加密SM2,在开发过程中遇到了该问题InvalidCipherTextException: invalid cipher text

【原因】 私钥和公钥值不是成对存在的,每次调用SmUtil.sm2()会生成不同的随机密钥对。

【解决】在该Starter中采用@PostConstruct修饰方法,在项目运行中只会初始化运行一次该方法,保证了SmUtil.sm2()只会调用一次,不会生成不同的随机秘钥对。

ISSUES#1890】详细请看该地址:https://hub.fgit.cf/dromara/hutool/issues/1890

/*** @author xbhog* @date 2024/02/01 13:23**/
@Slf4j
@Component
public class EncryAdecryHolder {public static SM2 sm2 = null;@PostConstructpublic void encryHolder(){KeyPair pair = SecureUtil.generateKeyPair("SM2");byte[] privateKey = pair.getPrivate().getEncoded();byte[] publicKey = pair.getPublic().getEncoded();log.info("生成的公钥:{}",publicKey);log.info("生成的私钥:{}",privateKey);sm2= SmUtil.sm2(privateKey, publicKey);}
}

除了默认的加密方式,还可以通过SecurityHandler接口进行扩展,扩展出来的impl可以在@SecuritySupport(securityHandler="xxxxxx")中指定。

/*** @author xbhog* @describe: 全局加解密注解* @date 2023/6/8*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuritySupport {/*securityHandlerImpl*/String securityHandler() default "securityHandlerImpl";String exceptionResponse() default "";}

测试

复用之前的测试项目,引用打包的mavne依赖:

<dependency><groupId>com.xbhog</groupId><artifactId>encryAdecry-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>

启动项目,初始化公私钥。


测试接口代码如下:

@Slf4j
@RestController
public class BasicController implements ApplicationContextAware {@Resource(name = "demoSecurityHandlerImpl")private SecurityHandler encryAdecry;private ApplicationContext applicationContext;// http://127.0.0.1:8080/hello?name=lisi//@SecuritySupport(securityHandler = "demoSecurityHandlerImpl")@SecuritySupport@PostMapping("/hello")public String hello(@RequestBody String name) {return "Hello " + name;}@GetMapping("/configTest")public String configTest(@RequestParam("name") String name) {/*DemoBean demoBean = applicationContext.getBean(DemoBean.class);demoBean.getDemo();*/return encryAdecry.encrypt(name);//return MD5.create().digestHex16(name);}
}

优化

优化后的项目结构:

encryAdecry-spring-boot-starter
└── src└── main└── java└── com.xbhog├── advice│   ├──ResponseBodyEncryptAdvice.java│   └──RequestBodyDecryptAdvice.java├── annotation│   └──SecuritySupport├── handler│    ├──impl│    │   └──EncryAdecryImpl.java│    └──SecurityHandler└── holder│    ├──ContextHolder.java│    └──SpringContextHolder.java├──GlobalProperties.java└──GlobalConfig.java└── resources└── META-INF└── spring.factories

增加配置类,用于绑定外部配置(propertiesYAML)到Java对象的的一种机制;

@Data
@ConfigurationProperties(GlobalProperties.PREFIX)
public class GlobalProperties {/*** 默认前缀*/public static final String PREFIX = "encryption.type";/*** 加解密算法*/private String algorithmType;/*** 加解密key值*/private String key;
}

注解修改:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuritySupport {/*** 项目默认加解密实现类encryAdecryImpl* */String securityHandler() default "encryAdecryImpl";}

重写Starter默认的加解密方式:

@Slf4j
@Component
public class EncryAdecryImpl implements SecurityHandler {@Resourceprivate GlobalProperties globalProperties;private static volatile SM2 sm2;@Overridepublic String encrypt(String original) {log.info("【starter】具体加密的数据{}",original);return sm2.encryptBase64(original, KeyType.PublicKey);}@Overridepublic String decrypt(String original) {String decryptData = StrUtil.utf8Str(sm2.decryptStr(original, KeyType.PrivateKey));log.info("【starter】具体解密的数据:{}",decryptData);return decryptData;}@PostConstruct@Overridepublic void init() {log.info("======>获取映射的加密算法类型:{}",globalProperties.getAlgorithmType());//传的是加密算法KeyPair pair = SecureUtil.generateKeyPair(globalProperties.getAlgorithmType());byte[] privateKey = pair.getPrivate().getEncoded();byte[] publicKey = pair.getPublic().getEncoded();sm2= SmUtil.sm2(privateKey, publicKey);}
}
http://www.hrbkazy.com/news/5719.html

相关文章:

  • 跨平台app开发工具seo搜索铺文章
  • 定州网站建设百度搜索网址大全
  • 泉州网站建设哪家好池州网站seo
  • 做网站遇到竞争对手怎么办网络营销管理办法
  • 东南亚做网站 什么语言市场监督管理局电话
  • 做微信商城设计网站广州网站营销推广
  • 泰州做直销会员结算管理网站快速排名生客seo
  • 如何选择网站开发公司免费域名申请的方法
  • 无锡祥搜做网站推广云南省最新疫情情况
  • 公司介绍文案范文aso优化教程
  • web网站开发基本流程百度的相关搜索
  • 郑州治疗精神病哪家好百度搜索引擎关键词优化
  • 红河做网站的公司浙江seo技术培训
  • 做网站推广员图片处理问题好口碑的关键词优化
  • 德宏做网站百度账号查询
  • 河南住房和城乡建设厅门户网站西安seo网站排名
  • 青岛做网站哪个公司好怎样建立自己的网站平台
  • 公司做网站的开支会计分录怎么做seo是哪个英文的缩写
  • 建筑素材网站海外短视频软件
  • 图片1600px做网站东莞有限公司seo
  • 外贸公司网站怎么做湖南企业竞价优化
  • 供应链管理系统实验报告济南网络优化网站
  • 优惠网站如何做营销推广软文
  • 网站各页面网店培训教程
  • 建设网站用哪种语言千锋教育的口碑怎么样
  • 网站中的打赏怎么做的1688自然排名怎么做好
  • 小白怎么学做网站360免费建站系统
  • 汽车配件网上商城在线工具seo
  • 建搜索型网站网络推广外包公司哪家好
  • 自己怎么做公司网站seo优质友链购买