增加搜索历史注解-可记录当前用户检索历史

v1.4.1
Parker 4 years ago
parent 93d5460eef
commit 3805b8b993

@ -1,4 +1,4 @@
package org.opsli.common.annotation.limiter;
package org.opsli.common.annotation;
import org.opsli.common.enums.AlertType;

@ -0,0 +1,29 @@
package org.opsli.common.annotation;
import java.lang.annotation.*;
/**
*
*
* key
*
* @author Parker
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SearchHis {
/**
* key url key
*
* http://127.0.0.1/opsli-boot?username=123
*
* username key
*
* 使 username_EQ key
*
*/
String[] keys();
}

@ -37,6 +37,9 @@ public interface OrderConstants {
/** 参数非法验证顺序 */
int PARAM_VALIDATE_AOP_SORT = 185;
/** 搜索历史 */
int SEARCH_HIS_AOP_SORT = 186;
/** SQL 切面执行顺序 */
int SQL_ORDER = 190;

@ -95,7 +95,7 @@ public final class RateLimiterUtil {
*/
public static boolean enter(String clientIpAddress, String resource, Double dfQps) {
// 计时器
TimeInterval timer = DateUtil.timer();
long t1 = System.currentTimeMillis();
Map<String, RateLimiterInner> rateLimiterInnerMap;
try {
@ -141,15 +141,11 @@ public final class RateLimiterUtil {
//非阻塞
if (!rateLimiter.tryAcquire(Duration.ofMillis(DEFAULT_WAIT))) {
// 花费毫秒数
long timerCount = timer.interval();
//限速中,提示用户
log.error("限流器 - 访问频繁 耗时: "+ timerCount + "ms, IP地址: " + clientIpAddress + ", URI: " + resource);
log.error("限流器 - 访问频繁 耗时: "+ (System.currentTimeMillis() - t1) + "ms, IP地址: " + clientIpAddress + ", URI: " + resource);
return false;
} else {
// 正常访问
// 花费毫秒数
long timerCount = timer.interval();
return true;
}
}

@ -22,7 +22,7 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.opsli.common.annotation.limiter.Limiter;
import org.opsli.common.annotation.Limiter;
import org.opsli.common.enums.AlertType;
import org.opsli.common.exception.ServiceException;
import org.opsli.common.utils.OutputStreamUtil;
@ -52,7 +52,7 @@ import static org.opsli.common.constants.OrderConstants.LIMITER_AOP_SORT;
public class LimiterAop {
@Pointcut("@annotation(org.opsli.common.annotation.limiter.Limiter)")
@Pointcut("@annotation(org.opsli.common.annotation.Limiter)")
public void requestMapping() {
}

@ -0,0 +1,81 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.core.aspect;
import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.opsli.common.annotation.SearchHis;
import org.opsli.core.utils.SearchHisUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import static org.opsli.common.constants.OrderConstants.SEARCH_HIS_AOP_SORT;
/**
* AOP
*
* @author
* @date 2020-09-16
*/
@Slf4j
@Order(SEARCH_HIS_AOP_SORT)
@Aspect
@Component
public class SearchHisAop {
@Pointcut("@annotation(org.opsli.common.annotation.SearchHis)")
public void requestMapping() {
}
/**
*
* @param point
*/
@Before("requestMapping()")
public void limiterHandle(JoinPoint point){
try {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
if(sra != null) {
HttpServletRequest request = sra.getRequest();
SearchHis searchHis = method.getAnnotation(SearchHis.class);
if(searchHis != null){
String[] keys = searchHis.keys();
// 存入缓存
SearchHisUtil.putSearchHis(request, Convert.toList(String.class, keys));
}
}
}catch (Exception e){
log.error(e.getMessage(),e);
}
}
}

@ -17,12 +17,10 @@ package org.opsli.core.utils;
import com.google.code.kaptcha.Producer;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.web.system.dict.DictDetailApi;
import org.opsli.common.constants.CacheConstants;
import org.opsli.common.exception.TokenException;
import org.opsli.common.utils.Props;
import org.opsli.core.msg.TokenMsg;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.RedisPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;

@ -23,9 +23,8 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.dict.DictDetailApi;
import org.opsli.api.web.system.menu.MenuApi;
import org.opsli.api.wrapper.system.dict.DictWrapper;
import org.opsli.api.wrapper.system.dict.DictDetailModel;
import org.opsli.api.wrapper.system.dict.DictWrapper;
import org.opsli.common.constants.CacheConstants;
import org.opsli.common.constants.DictConstants;
import org.opsli.core.cache.local.CacheUtil;

@ -19,11 +19,9 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.menu.MenuApi;
import org.opsli.api.web.system.user.UserApi;
import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.cache.pushsub.msgs.MenuMsgFactory;
import org.opsli.core.cache.pushsub.msgs.OrgMsgFactory;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.RedisPlugin;
import org.opsli.plugins.redis.lock.RedisLock;

@ -18,12 +18,9 @@ package org.opsli.core.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.menu.MenuApi;
import org.opsli.api.web.system.user.UserApi;
import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.cache.pushsub.msgs.MenuMsgFactory;
import org.opsli.core.cache.pushsub.msgs.OrgMsgFactory;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.RedisPlugin;

@ -0,0 +1,129 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.core.utils;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.constants.CacheConstants;
import org.opsli.common.utils.Props;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.RedisPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
/**
* @Author:
* @CreateTime: 2020-09-22 11:17
* @Description:
*/
@Slf4j
@Order(UTIL_ORDER)
@Component
@Lazy(false)
@AutoConfigureAfter({RedisPlugin.class , RedisLockPlugins.class})
public class SearchHisUtil {
/** 搜索历史缓存数据KEY */
private static final int DEFAULT_COUNT = 10;
/**
*
*/
public static final String PREFIX_NAME;
private static final String CACHE_PREFIX = "his:username:";
/** Redis插件 */
private static RedisPlugin redisPlugin;
static {
Props props = new Props("application.yaml");
PREFIX_NAME = props.getStr("spring.cache-conf.prefix", CacheConstants.PREFIX_NAME) + ":";
}
/**
*
* @param key
* @param count
*/
public static Set<Object> getSearchHis(HttpServletRequest request, String key, Integer count) {
if(request == null || StringUtils.isEmpty(key)){
return null;
}
if(count == null){
count = DEFAULT_COUNT;
}
// 获得当前用户
UserModel user = UserUtil.getUser();
String cacheKey = PREFIX_NAME + CACHE_PREFIX + user.getUsername() + ":" + key;
return redisPlugin.zReverseRange(cacheKey, 0, count - 1);
}
/**
*
* @param request
* @param keys key
*/
public static void putSearchHis(HttpServletRequest request, List<String> keys) {
if(request == null || CollUtil.isEmpty(keys)){
return;
}
// 获得当前用户
UserModel user = UserUtil.getUser();
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : keys) {
String[] values = parameterMap.get(key);
if(values == null || values.length == 0){
continue;
}
String cacheKey = PREFIX_NAME + CACHE_PREFIX + user.getUsername() + ":" + key;
String val = values[0];
// 记录
redisPlugin.zIncrementScore(cacheKey, val, 1);
}
}
// ===================================
@Autowired
public void setRedisPlugin(RedisPlugin redisPlugin) {
SearchHisUtil.redisPlugin = redisPlugin;
}
}

@ -20,13 +20,8 @@ import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.tenant.TenantApi;
import org.opsli.api.wrapper.system.tenant.TenantModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.common.exception.TokenException;
import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.cache.pushsub.msgs.OrgMsgFactory;
import org.opsli.core.cache.pushsub.msgs.TenantMsgFactory;
import org.opsli.core.msg.TokenMsg;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.plugins.redis.RedisLockPlugins;
import org.opsli.plugins.redis.RedisPlugin;
import org.opsli.plugins.redis.lock.RedisLock;
@ -36,8 +31,6 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
/**

@ -30,13 +30,11 @@ import org.opsli.common.constants.CacheConstants;
import org.opsli.common.constants.SignConstants;
import org.opsli.common.constants.TokenConstants;
import org.opsli.common.constants.TokenTypeConstants;
import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException;
import org.opsli.common.utils.Props;
import org.opsli.core.msg.TokenMsg;
import org.opsli.plugins.redis.RedisPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;

@ -29,7 +29,6 @@ import org.opsli.common.api.TokenThreadLocal;
import org.opsli.common.exception.TokenException;
import org.opsli.common.utils.Props;
import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.cache.pushsub.msgs.MenuMsgFactory;
import org.opsli.core.cache.pushsub.msgs.UserMsgFactory;
import org.opsli.core.msg.TokenMsg;
import org.opsli.plugins.redis.RedisLockPlugins;

@ -23,7 +23,7 @@ import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.wrapper.system.tenant.TenantModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.limiter.Limiter;
import org.opsli.common.annotation.Limiter;
import org.opsli.common.api.TokenThreadLocal;
import org.opsli.common.enums.AlertType;
import org.opsli.common.exception.TokenException;

@ -0,0 +1,66 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.modulars.tools.searchhis.web;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.opsli.api.base.result.ResultVo;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.Limiter;
import org.opsli.common.annotation.SearchHis;
import org.opsli.core.utils.SearchHisUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
/**
*
*
* @author parker
* @date 2020-05-23 13:30
**
*/
@Slf4j
@RestController
@ApiRestController("/searchhis")
public class SearchHisRestController {
/**
*
*/
@Limiter
@ApiOperation(value = "获得搜索历史记录", notes = "获得搜索历史记录")
@PostMapping("/getSearchHis")
public ResultVo<?> getSearchHis(String key, Integer count, HttpServletRequest request){
Set<Object> searchHis = SearchHisUtil.getSearchHis(request, key, count);
return ResultVo.success(searchHis);
}
/**
*
*/
@Limiter
@SearchHis(keys = {"test"})
@ApiOperation(value = "测试存入搜索历史记录", notes = "测试存入搜索历史记录")
@PostMapping("/testPutSearchHis")
public void getSearchHis(String test, HttpServletRequest request){
}
}
Loading…
Cancel
Save