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

网站系统改教程网站设计与管理

网站系统改教程,网站设计与管理,做网站怎么上传图片,网站备案模板承接上文#xff08;传送门 —《面试必考》 — AOP-CSDN博客#xff09;#xff0c;在被面试官拷打的时候#xff0c;会被问到一个致命问题#xff1a;“你了解aop吗#xff1f;有具体的使用经验吗#xff1f;” 你#xff1a;......... 言尽于此#xff0c;此篇…承接上文传送门 —《面试必考》 — AOP-CSDN博客在被面试官拷打的时候会被问到一个致命问题“你了解aop吗有具体的使用经验吗” 你......... 言尽于此此篇文章必能大补 自定义注解①连续点击注解 package com.ruoyi.profile.lock;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RequestLock {String key() default ; // 主键前缀long duration() default 2000; // 默认防抖时间单位毫秒boolean useIp() default true; // 是否使用IP作为键的一部分boolean useUserId() default true; // 是否使用用户ID作为键的一部分 }package com.ruoyi.profile.lock;import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit;import static com.ruoyi.common.constant.HttpStatus.WARN; import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;Aspect Component Order(2) public class RequestLockAspect {Resourceprivate StringRedisTemplate stringRedisTemplate;Around(execution(public * * (..)) annotation(requestLock))public Object handleDebounce(ProceedingJoinPoint joinPoint, RequestLock requestLock) throws Throwable {String key generateKey(joinPoint, requestLock);Object proceed joinPoint.proceed();if (Boolean.FALSE.equals(stringRedisTemplate.hasKey(key))) {stringRedisTemplate.opsForValue().set(key, true, requestLock.duration(), TimeUnit.MILLISECONDS);return proceed;} else {if (proceed instanceof TableDataInfo) {TableDataInfo rspData new TableDataInfo();rspData.setCode(WARN);rspData.setMsg(请求太频繁请稍后再试!!!);return rspData;} else if (proceed instanceof AjaxResult) {// 返回一个默认值或抛出异常根据业务需求决定return AjaxResult.error(请求太频繁请稍后再试!!!);} else {throw new RuntimeException(未知返回错误);}}}private String generateKey(ProceedingJoinPoint joinPoint, RequestLock requestLock) {HttpServletRequest request ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();StringBuilder sb new StringBuilder();Object[] args joinPoint.getArgs();for (Object arg : args) {sb.append(:).append(arg.toString());}// 根据注解参数构建键sb.append(requestLock.key());if (requestLock.useIp()) {sb.append(:).append(request.getRemoteAddr()); // 获取客户端IP}if (requestLock.useUserId()) {// 假设用户ID可以从某个地方获取比如从session或token中Long userId getLoginUser().getUserId();sb.append(:).append(userId);}return sb.toString();}}自定义注解②限流注解 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.enums.LimitType;/*** 限流注解* * author */ Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface RateLimiter {/*** 限流key*/public String key() default CacheConstants.RATE_LIMIT_KEY;/*** 限流时间,单位秒*/public int time() default 60;/*** 限流次数*/public int count() default 100;/*** 限流类型*/public LimitType limitType() default LimitType.DEFAULT; }import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.script.RedisScript; import org.springframework.stereotype.Component; import com.ruoyi.common.annotation.RateLimiter; import com.ruoyi.common.enums.LimitType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ip.IpUtils;/*** 限流处理** author */ Aspect Component public class RateLimiterAspect {private static final Logger log LoggerFactory.getLogger(RateLimiterAspect.class);private RedisTemplateObject, Object redisTemplate;private RedisScriptLong limitScript;Autowiredpublic void setRedisTemplate1(RedisTemplateObject, Object redisTemplate){this.redisTemplate redisTemplate;}Autowiredpublic void setLimitScript(RedisScriptLong limitScript){this.limitScript limitScript;}Before(annotation(rateLimiter))public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable{int time rateLimiter.time();int count rateLimiter.count();String combineKey getCombineKey(rateLimiter, point);ListObject keys Collections.singletonList(combineKey);try{Long number redisTemplate.execute(limitScript, keys, count, time);if (StringUtils.isNull(number) || number.intValue() count){throw new ServiceException(访问过于频繁请稍候再试);}log.info(限制请求{},当前请求{},缓存key{}, count, number.intValue(), combineKey);}catch (ServiceException e){throw e;}catch (Exception e){throw new RuntimeException(服务器限流异常请稍候再试);}}public String getCombineKey(RateLimiter rateLimiter, JoinPoint point){StringBuffer stringBuffer new StringBuffer(rateLimiter.key());if (rateLimiter.limitType() LimitType.IP){stringBuffer.append(IpUtils.getIpAddr()).append(-);}MethodSignature signature (MethodSignature) point.getSignature();Method method signature.getMethod();Class? targetClass method.getDeclaringClass();stringBuffer.append(targetClass.getName()).append(-).append(method.getName());return stringBuffer.toString();} }限流方式其实有很多种比如说Nginx漏桶算法、Gateway令牌桶算法、Sentinel、CircuitBreaker、自定义注解限流、自定义过滤器、自定义拦截器等等。 Gateway参考链接Spring Cloud Gateway 限流详解-腾讯云开发者社区-腾讯云 (tencent.com) 如果不明白最后三个的区别传送门 —《面试必考》 — AOP-CSDN博客 自定义注解③日志注解 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.OperatorType;/*** 自定义操作日志记录注解* * author **/ Target({ ElementType.PARAMETER, ElementType.METHOD }) Retention(RetentionPolicy.RUNTIME) Documented public interface Log {/*** 模块*/public String title() default ;/*** 功能*/public BusinessType businessType() default BusinessType.OTHER;/*** 操作人类别*/public OperatorType operatorType() default OperatorType.MANAGE;/*** 是否保存请求的参数*/public boolean isSaveRequestData() default true;/*** 是否保存响应的参数*/public boolean isSaveResponseData() default true;/*** 排除指定的请求参数*/public String[] excludeParamNames() default {}; }package com.ruoyi.framework.aspectj;import java.util.Collection; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.ArrayUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.NamedThreadLocal; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; import com.alibaba.fastjson2.JSON; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.filter.PropertyPreExcludeFilter; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.system.domain.SysOperLog;/*** 操作日志记录处理* * author */ Aspect Component public class LogAspect {private static final Logger log LoggerFactory.getLogger(LogAspect.class);/** 排除敏感属性字段 */public static final String[] EXCLUDE_PROPERTIES { password, oldPassword, newPassword, confirmPassword };/** 计算操作消耗时间 */private static final ThreadLocalLong TIME_THREADLOCAL new NamedThreadLocalLong(Cost Time);/*** 处理请求前执行*/Before(value annotation(controllerLog))public void boBefore(JoinPoint joinPoint, Log controllerLog){TIME_THREADLOCAL.set(System.currentTimeMillis());}/*** 处理完请求后执行** param joinPoint 切点*/AfterReturning(pointcut annotation(controllerLog), returning jsonResult)public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult){handleLog(joinPoint, controllerLog, null, jsonResult);}/*** 拦截异常操作* * param joinPoint 切点* param e 异常*/AfterThrowing(value annotation(controllerLog), throwing e)public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e){handleLog(joinPoint, controllerLog, e, null);}protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult){try{// 获取当前的用户LoginUser loginUser SecurityUtils.getLoginUser();// *数据库日志*//SysOperLog operLog new SysOperLog();operLog.setStatus(BusinessStatus.SUCCESS.ordinal());// 请求的地址String ip IpUtils.getIpAddr();operLog.setOperIp(ip);operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));if (loginUser ! null){operLog.setOperName(loginUser.getUsername());SysUser currentUser loginUser.getUser();if (StringUtils.isNotNull(currentUser) StringUtils.isNotNull(currentUser.getDept())){operLog.setDeptName(currentUser.getDept().getDeptName());}}if (e ! null){operLog.setStatus(BusinessStatus.FAIL.ordinal());operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));}// 设置方法名称String className joinPoint.getTarget().getClass().getName();String methodName joinPoint.getSignature().getName();operLog.setMethod(className . methodName ());// 设置请求方式operLog.setRequestMethod(ServletUtils.getRequest().getMethod());// 处理设置注解上的参数getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);// 设置消耗时间operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());// 保存数据库AsyncManager.me().execute(AsyncFactory.recordOper(operLog));}catch (Exception exp){// 记录本地异常日志log.error(异常信息:{}, exp.getMessage());exp.printStackTrace();}finally{TIME_THREADLOCAL.remove();}}/*** 获取注解中对方法的描述信息 用于Controller层注解* * param log 日志* param operLog 操作日志* throws Exception*/public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception{// 设置action动作operLog.setBusinessType(log.businessType().ordinal());// 设置标题operLog.setTitle(log.title());// 设置操作人类别operLog.setOperatorType(log.operatorType().ordinal());// 是否需要保存request参数和值if (log.isSaveRequestData()){// 获取参数的信息传入到数据库中。setRequestValue(joinPoint, operLog, log.excludeParamNames());}// 是否需要保存response参数和值if (log.isSaveResponseData() StringUtils.isNotNull(jsonResult)){operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));}}/*** 获取请求的参数放到log中* * param operLog 操作日志* throws Exception 异常*/private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception{Map?, ? paramsMap ServletUtils.getParamMap(ServletUtils.getRequest());String requestMethod operLog.getRequestMethod();if (StringUtils.isEmpty(paramsMap) (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))){String params argsArrayToString(joinPoint.getArgs(), excludeParamNames);operLog.setOperParam(StringUtils.substring(params, 0, 2000));}else{operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));}}/*** 参数拼装*/private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames){String params ;if (paramsArray ! null paramsArray.length 0){for (Object o : paramsArray){if (StringUtils.isNotNull(o) !isFilterObject(o)){try{String jsonObj JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));params jsonObj.toString() ;}catch (Exception e){}}}}return params.trim();}/*** 忽略敏感属性*/public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames){return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));}/*** 判断是否需要过滤的对象。* * param o 对象信息。* return 如果是需要过滤的对象则返回true否则返回false。*/SuppressWarnings(rawtypes)public boolean isFilterObject(final Object o){Class? clazz o.getClass();if (clazz.isArray()){return clazz.getComponentType().isAssignableFrom(MultipartFile.class);}else if (Collection.class.isAssignableFrom(clazz)){Collection collection (Collection) o;for (Object value : collection){return value instanceof MultipartFile;}}else if (Map.class.isAssignableFrom(clazz)){Map map (Map) o;for (Object value : map.entrySet()){Map.Entry entry (Map.Entry) value;return entry.getValue() instanceof MultipartFile;}}return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse|| o instanceof BindingResult;} }言尽于此记得按时吃饭。社会的边角料老妈的小骄傲你我都有光明的未来
http://www.w-s-a.com/news/35713/

相关文章:

  • 服装 网站模板 wordpress石家庄做网站的公司有哪些
  • 惠州技术支持网站建设百度怎样注册免费的网站
  • 无锡哪里有做网站的公司泸州网站建设公司
  • 怎么进行网站推广jsp可以做那些小网站
  • 懒人手机网站wordpress修改秒速
  • WordPress资讯网站用花生壳做网站
  • 关于营销方面的网站建设网站怎么克隆
  • 站长网seo综合查询工具电商公司简介
  • 全能网站建设教程广告制作公司需要什么设备
  • 汽车行业做网站网站改版seo建议
  • 建设职业注册中心网站photoshop属于什么软件
  • 公司网站展示有哪些wordpress工单
  • iis新建网站seo是做什么工作的
  • 临沂网站建设厂家做外贸的女生现状
  • 电子商务网站建设实践临沂做网站的
  • 网站职能建设论文做外贸都有哪些网站
  • 网站建设项目需求分析房地产网站源码
  • 网站充值提现公司账务怎么做中国能建设计公司网站
  • 网站信息资源建设包括哪些网站网站做维护
  • 网站性能优化的方法有哪些建设施工合同网站
  • 郑州建设企业网站山西省住房和城乡建设厅网站
  • 做网站的去哪找客户正规制作网站公司
  • 网站代理访问是什么意思外国优秀设计网站
  • 合肥个人建站模板网络技术服务有限公司
  • 做网站什么公司好dw企业网站开发教程
  • 怎么做自己的个人网站宝安网站设计哪家最好
  • 浩博建设集团网站站长网站统计
  • 电商网站开发视频seo排名优化方式方法
  • 宿迁市住房城乡建设局网站wordpress纯图片主题
  • 广州建设网站 公司湖北省建设信息网官网