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

做视频的网站多少钱网站排名点击工具

做视频的网站多少钱,网站排名点击工具,个人网站建设的参考文献,上海app开发费用背景 我们把数据存到数据库的时候#xff0c;有些敏感字段是需要加密的#xff0c;从数据库查出来再进行解密。如果存在多张表或者多个地方需要对部分字段进行加解密操作#xff0c;每个地方都手写一次加解密的动作#xff0c;显然不是最好的选择。如果我们使用的是Mybati…背景 我们把数据存到数据库的时候有些敏感字段是需要加密的从数据库查出来再进行解密。如果存在多张表或者多个地方需要对部分字段进行加解密操作每个地方都手写一次加解密的动作显然不是最好的选择。如果我们使用的是Mybatis框架那就跟着一起探索下如何使用框架的拦截器功能实现自动加解密吧。 定义一个自定义注解 我们需要一个注解只要实体类的属性加上这个注解那么就对这个属性进行自动加解密。我们把这个注解定义灵活一点不仅可以放在属性上还可以放到类上如果在类上使用这个注解代表这个类的所有属性都进行自动加密。 /*** 加密字段*/ Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.TYPE}) public interface EncryptField {}定义实体类 package com.wen3.demo.mybatisplus.po;import com.baomidou.mybatisplus.annotation.*; import com.wen3.demo.mybatisplus.encrypt.annotation.EncryptField; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors;EncryptField Getter Setter Accessors(chain true) KeySequence(value t_user_user_id_seq, dbType DbType.POSTGRE_SQL) TableName(t_USER) public class UserPo {/*** 用户id*/TableId(value USER_ID, type IdType.INPUT)private Long userId;/*** 用户姓名*/TableField(USER_NAME)private String userName;/*** 用户性别*/TableField(USER_SEX)private String userSex;/*** 用户邮箱*/EncryptFieldTableField(USER_EMAIL)private String userEmail;/*** 用户账号*/TableField(USER_ACCOUNT)private String userAccount;/*** 用户地址*/TableField(USER_ADDRESS)private String userAddress;/*** 用户密码*/TableField(USER_PASSWORD)private String userPassword;/*** 用户城市*/TableField(USER_CITY)private String userCity;/*** 用户状态*/TableField(USER_STATUS)private String userStatus;/*** 用户区县*/TableField(USER_SEAT)private String userSeat; }拦截器 Mybatis-Plus有个拦截器接口com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor但发现这个接口有一些不足 必须构建一个MybatisPlusInterceptor这样的Bean并调用这个Bean的addInnerInterceptor方法把所有的InnerInterceptor加入进去才能生效InnerInterceptor只有before拦截缺省after拦截。加密可以在before里面完成但解密需要在after里面完成所以这个InnerInterceptor不能满足我们的要求 所以继续研究源码发现Mybatis有个org.apache.ibatis.plugin.Interceptor接口这个接口能满足我对自动加解密的所有诉求 首先实现Interceptor接口只要注册成为Spring容器的Bean拦截器就能生效可以更加灵活的在before和after之间插入自己的逻辑 加密拦截器 创建名为EncryptInterceptor的加密拦截器对update操作进行拦截对带EncryptField注解的字段进行加密处理无论是save方法还是saveBatch方法都会被成功拦截到。 package com.wen3.demo.mybatisplus.encrypt.interceptor;import com.wen3.demo.mybatisplus.encrypt.annotation.EncryptField; import com.wen3.demo.mybatisplus.encrypt.util.FieldEncryptUtil; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Signature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.Objects;/*** 对update操作进行拦截对{link EncryptField}字段进行加密处理* 无论是save方法还是saveBatch方法都会被成功拦截*/ Slf4j Intercepts({Signature(type Executor.class, method update, args {MappedStatement.class, Object.class}) }) Component public class EncryptInterceptor implements Interceptor {private static final String METHOD update;Setter(onMethod_ {Autowired})private FieldEncryptUtil fieldEncryptUtil;Overridepublic Object intercept(Invocation invocation) throws Throwable {if(!StringUtils.equals(METHOD, invocation.getMethod().getName())) {return invocation.proceed();}// 根据update拦截规则第0个参数一定是MappedStatement第1个参数是需要进行判断的参数Object param invocation.getArgs()[1];if(Objects.isNull(param)) {return invocation.proceed();}// 加密处理fieldEncryptUtil.encrypt(param);return invocation.proceed();} }解密拦截器 创建名为DecryptInterceptor的加密拦截器对query操作进行拦截对带EncryptField注解的字段进行解密处理无论是返回单个对象还是对象的集合都会被拦截到。 package com.wen3.demo.mybatisplus.encrypt.interceptor;import cn.hutool.core.util.ClassUtil; import com.wen3.demo.mybatisplus.encrypt.annotation.EncryptField; import com.wen3.demo.mybatisplus.encrypt.util.FieldEncryptUtil; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Signature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.sql.Statement; import java.util.Collection;/*** 对query操作进行拦截对{link EncryptField}字段进行解密处理*/ Slf4j Intercepts({Signature(type ResultSetHandler.class, method handleResultSets, args Statement.class) }) Component public class DecryptInterceptor implements Interceptor {private static final String METHOD query;Setter(onMethod_ {Autowired})private FieldEncryptUtil fieldEncryptUtil;SuppressWarnings(rawtypes)Overridepublic Object intercept(Invocation invocation) throws Throwable {Object result invocation.proceed();// 解密处理// 经过测试发现无论是返回单个对象还是集合result都是ArrayList类型if(ClassUtil.isAssignable(Collection.class, result.getClass())) {fieldEncryptUtil.decrypt((Collection) result);} else {fieldEncryptUtil.decrypt(result);}return result;} }加解密工具类 由于加密和解密绝大部分的逻辑是相似的不同的地方在于 加密需要通过反射处理的对象是在SQL执行前是Invocation对象的参数列表中下标为1的参数而解决需要通过反射处理的对象是在SQL执行后对执行结果对象进行解密处理。一个是获取到字段值进行加密一个是获取到字段值进行解密 于是把加解密逻辑抽象成一个工具类把差异的部分做为参数传入 package com.wen3.demo.mybatisplus.encrypt.util;import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ReflectUtil; import com.wen3.demo.mybatisplus.encrypt.annotation.EncryptField; import com.wen3.demo.mybatisplus.encrypt.service.FieldEncryptService; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils;import java.lang.reflect.Field; import java.util.Collection; import java.util.List; import java.util.Objects;/*** 加解密工具类*/ Slf4j Component public class FieldEncryptUtil {Setter(onMethod_ {Autowired})private FieldEncryptService fieldEncryptService;/**对EncryptField注解进行加密处理*/public void encrypt(Object obj) {if(ClassUtil.isPrimitiveWrapper(obj.getClass())) {return;}encryptOrDecrypt(obj, true);}/**对EncryptField注解进行解密处理*/public void decrypt(Object obj) {encryptOrDecrypt(obj, false);}/**对EncryptField注解进行解密处理*/public void decrypt(Collection list) {if(CollectionUtils.isEmpty(list)) {return;}list.forEach(this::decrypt);}/**对EncryptField注解进行加解密处理*/private void encryptOrDecrypt(Object obj, boolean encrypt) {// 根据update拦截规则第0个参数一定是MappedStatement第1个参数是需要进行判断的参数if(Objects.isNull(obj)) {return;}// 获取所有带加密注解的字段ListField encryptFields null;// 判断类上面是否有加密注解EncryptField encryptField AnnotationUtils.findAnnotation(obj.getClass(), EncryptField.class);if(Objects.nonNull(encryptField)) {// 如果类上有加密注解则所有字段都需要加密encryptFields FieldUtils.getAllFieldsList(obj.getClass());} else {encryptFields FieldUtils.getFieldsListWithAnnotation(obj.getClass(), EncryptField.class);}// 没有字段需要加密则跳过if(CollectionUtils.isEmpty(encryptFields)) {return;}encryptFields.forEach(f-{// 只支持String类型的加密if(!ClassUtil.isAssignable(String.class, f.getType())) {return;}String oldValue (String) ReflectUtil.getFieldValue(obj, f);if(StringUtils.isBlank(oldValue)) {return;}String logText null, newValue null;if(encrypt) {logText encrypt;newValue fieldEncryptService.encrypt(oldValue);} else {logText decrypt;newValue fieldEncryptService.decrypt(oldValue);}log.info({} success[{}{}]. before:{}, after:{}, logText, f.getDeclaringClass().getName(), f.getName(), oldValue, newValue);ReflectUtil.setFieldValue(obj, f, newValue);});} }加解密算法 Mybatis-Plus自带了一个AES加解密算法的工具我们只需要提供一个加密key然后就可以完成一个加解密的业务处理了。 先定义一个加解密接口 package com.wen3.demo.mybatisplus.encrypt.service;/*** 数据加解密接口*/ public interface FieldEncryptService {/**对数据进行加密*/String encrypt(String value);/**对数据进行解密*/String decrypt(String value);/**判断数据是否忆加密*/default boolean isEncrypt(String value) {return false;} }然后实现一个默认的加解密实现类 package com.wen3.demo.mybatisplus.encrypt.service.impl;import cn.hutool.core.util.ClassUtil; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.AES; import com.wen3.demo.mybatisplus.encrypt.service.FieldEncryptService; import org.springframework.stereotype.Component;import javax.crypto.IllegalBlockSizeException;/*** 使用Mybatis-Plus自带的AES加解密*/ Component public class DefaultFieldEncryptService implements FieldEncryptService {private static final String ENCRYPT_KEY abcdefghijklmnop;Overridepublic String encrypt(String value) {if(isEncrypt(value)) {return value;}return AES.encrypt(value, ENCRYPT_KEY);}Overridepublic String decrypt(String value) {return AES.decrypt(value, ENCRYPT_KEY);}Overridepublic boolean isEncrypt(String value) {// 判断是否已加密try {// 解密成功说明已加密decrypt(value);return true;} catch (MybatisPlusException e) {if(ClassUtil.isAssignable(IllegalBlockSizeException.class, e.getCause().getClass())) {return false;}throw e;}} }自动加解密单元测试 package com.wen3.demo.mybatisplus.service;import cn.hutool.core.util.RandomUtil; import com.wen3.demo.mybatisplus.MybatisPlusSpringbootTestBase; import com.wen3.demo.mybatisplus.encrypt.service.FieldEncryptService; import com.wen3.demo.mybatisplus.po.UserPo; import jakarta.annotation.Resource; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.Test;import java.util.Collections; import java.util.List; import java.util.Map;class UserServiceTest extends MybatisPlusSpringbootTestBase {Resourceprivate UserService userService;Resourceprivate FieldEncryptService fieldEncryptService;Testvoid save() {UserPo userPo new UserPo();String originalValue RandomStringUtils.randomAlphabetic(16);String encryptValue fieldEncryptService.encrypt(originalValue);userPo.setUserEmail(originalValue);userPo.setUserName(RandomStringUtils.randomAlphabetic(16));boolean testResult userService.save(userPo);assertTrue(testResult);assertNotEquals(originalValue, userPo.getUserEmail());assertEquals(encryptValue, userPo.getUserEmail());// 测试解密: 返回单个对象UserPo userPoQuery userService.getById(userPo.getUserId());assertEquals(originalValue, userPoQuery.getUserEmail());// 测试解密: 返回ListListUserPo userPoList userService.listByEmail(encryptValue);assertEquals(originalValue, userPoList.get(0).getUserEmail());// 测试saveBatch方法也会被拦截加密userPo.setUserId(null);testResult userService.save(Collections.singletonList(userPo));assertTrue(testResult);assertNotEquals(originalValue, userPo.getUserEmail());assertEquals(encryptValue, userPo.getUserEmail());} }单元测试运行截图
http://www.yayakq.cn/news/1680/

相关文章:

  • 某某公司网站建设论文东营网站推广公司
  • 太原建设网站制作网站建设合同违约责任
  • 济南网站排名公司软件开发需要什么技术
  • 泉州网页网站制作2017做网站还赚钱吗
  • 外贸做企业什么网站盐城市住房城乡建设网站
  • 平度市城乡建设局网站上海企业服务云定位
  • 郑州做网站排名公司哪家好成都app定制公司
  • 江西网站设计服务网站建设价格标准
  • 织梦网站管理安装网站开发模块查相似
  • 青岛做网站公司网页设计策划书
  • wordpress快讯杭州seo招聘
  • wordpress站点备份现在写博客还是做网站
  • 重庆网站建设哪家公司好一般通过什么判断鱼的年龄
  • 做个网站多少钱一年静态门户网站源码
  • 帝国cms7.0网站搬家换域名换空间等安装教程深圳最好的区排名
  • 哪些企业网站做的好建设银行泰安培训中心官方网站
  • 微信网站的链接标志图片如何做电商网站主题
  • 网站用户体验优化wordpress 亚马逊插件
  • 网站的标签怎么修改温州专业网站建设
  • 如何查询网站的域名注册微信小程序定义
  • php网站建设难点seo短视频发布
  • 中山网站的优化建站网站赚钱吗
  • 北京建站公司兴田德润很好网络营销师报名官网
  • 网站上的动态背景怎么做的株洲外贸网站建设
  • 手机网站制作费用多少做网站及小程序需要会哪些技能
  • 建站公司的服务器阿里云apache重写wordpress
  • 510企业网站系统源码武鸣网站建设
  • 网站开发主页上海网站制作建设多少钱
  • c2c网站代表有哪些网站建设要做固定资产吗
  • 衡水自助建站系统哈尔滨市工程建设监理有限公司