常用工具组件

IPV4/V6校验合法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static Boolean isIP(String ip){
String ipReg = "^((1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|\\*)\\."
+ "((1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)|\\*)\\."
+ "((1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)|\\*)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])$";
Pattern ipPattern = Pattern.compile(ipReg);
return ipPattern.matcher(ip).matches();
}

public static boolean isIP(String ipAddress){
String ip="(2[5][0-5]|2[0-4]\\d|1\\d{2}|\\d{1,2})\\.(25[0-5]|2[0-4]\\d|1\\d{2}|\\d{1,2})\\.(25[0-5]|2[0-4]\\d|1\\d{2}|\\d{1,2})\\.(25[0-5]|2[0-4]\\d|1\\d{2}|\\d{1,2})";
Pattern pattern = Pattern.compile(ip);
Matcher matcher = pattern.matcher(ipAddress);
return matcher.matches();
}

public static Boolean isIPV6(String ip){
return ip != null && ip.contains(":") && ip.length() < 40;
}

Java stream 常用排序转化

1
2
3
4
5
6
7
// 使用 Stream 排序
list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());

// 按照[年龄]正序,但年龄中有一个 null 值
list = list.stream().sorted(Comparator.comparing(Person::getAge,
Comparator.nullsFirst(Integer::compareTo))).collect(Collectors.toList());

1
2
3
4
List<Long> memberIds = list.stream().map(AgentReviewMode::getMemberId).collect(Collectors.toList());

List<Member> memberList = memberMapper.queryMemberByMemberIdList(memberIds, HttpUtils.getSizeId());
Map<Long, Member> memberMap = memberList.stream().collect(Collectors.toMap(Member::getMemberId, Function.identity()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@AllArgsConstructor
@Getter
public enum VerifySceneEnum {
RETRIEVE_LOGIN_PASSWORD(1, "找回登录密码"),
RESET_PAYMENT_PASSWORD(2, "重置支付密码"),
CHANGE_MAILBOX(3, "修改邮箱"),
RESET_MAILBOX(4, "重置邮箱"),
RESET_SECURITY_PASSWORD(5, "重置安全密保"),
RESET_AUTHENTICATOR(6, "重置身份验证器");

private Integer code;
private String name;
private static final Map<Integer,String> sceneMap;
// private static final Map<Integer,VerifySceneEnum> sceneMap;
static {
sceneMap = Arrays.stream(VerifySceneEnum.values()).collect(Collectors.toMap(VerifySceneEnum::getCode,VerifySceneEnum::getName));
//sceneMap = Arrays.stream(VerifySceneEnum.values()).collect(Collectors.toMap(VerifySceneEnum::getCode,a->a));
}

public static String getVerifySceneStr(Integer code){
return sceneMap.get(code);
}

}

日志拦截组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

@Aspect
@Slf4j
@Component("agentControllerLogAspect")
public class ControllerLogAspect {

@Resource
private UserContext userContext;
@Resource
private RedisService redisService;

@Value("${agent.cache.default.time:4000}")
private long defaultCacheTime;

@Value("${response.parameter.length:6000}")
private int respParameterLength;

@Value("${agent.expert.limit.time:30}")
private long expertLimitTime;

@Resource
private Environment environment;


// 对于所有返回类型是Response对象的方法,如果执行出错了就封装一下
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
private void responseMethod() {

}


public static String getAllFiledValue(Object[] obj) {
if (obj == null) {
return "";
}
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < obj.length; i++) {
buffer.append(getAllFiledValue(obj[i]));
}
return buffer.toString();
}

public static String getAllFiledValue(Object obj) {
StringBuffer buffer = new StringBuffer("[" + obj.getClass().getSimpleName() + "(");
try {
Field[] fields = ReflectUtil.getFields(obj.getClass());
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Object fieldValue = ReflectUtil.getFieldValue(obj, field);
//是否有站点id字段,有进行赋值
if(field.getName().equals("stxx")){
if(fieldValue==null){
fieldValue=HttpUtils.getSizeId();
}
ReflectUtil.setFieldValue(obj,"stxx",fieldValue);
}
//为空不答应字段
if(fieldValue == null){
continue;
}else {
if(fieldValue instanceof String){
if(StrUtil.isBlank(Convert.toStr(fieldValue))){
continue;
} }
}
//是否包含脱敏关键字,包含进行脱敏
if(field.isAnnotationPresent(EncrypField.class)){
if (fieldValue != null && fieldValue instanceof String) {
String value = EncryptUtils.encrypt(Convert.toStr(fieldValue));
buffer.append(field.getName()).append("=").append(value);
}else {
buffer.append(field.getName()).append("=").append(fieldValue);
}
}else {
buffer.append(field.getName()).append("=").append(fieldValue);
}
if (i < fields.length - 1) {
buffer.append(",");
}
}
} catch (Exception e) {
log.error("获取参数值出错", e);
}
buffer.append(")");
return buffer.toString();
}

@Around("responseMethod()")
public Object process(ProceedingJoinPoint pjp) throws Throwable {
PageHelper.clearPage();
MethodSignature msig = (MethodSignature) pjp.getSignature();
Object target = pjp.getTarget();
String name = target.getClass().getSimpleName() + "." + msig.getName();
long start = System.currentTimeMillis();
Method method = msig.getMethod();
String url = HttpUtils.getRequest().getRequestURI();
try {
log.info("开始controller-{},url:{},参数:{},请求头{}", name, HttpUtils.getRequest().getRequestURI(), getAllFiledValue(pjp.getArgs()), HttpUtils.getHeaders());
//判断是否带有记录日志注解
long sTime = System.currentTimeMillis();
OperateLog annotation = method.getAnnotation(OperateLog.class);
if(annotation !=null){
String spel = annotation.operater();
String module = annotation.module();
String s = SpELUtils.parseSpel(method,pjp.getArgs(), spel);
String menu = SpELUtils.parseSpel(method,pjp.getArgs(), module);
OperateLogInfo attribute = (OperateLogInfo)HttpUtils.getRequest().getAttribute("com.kkcloud.core.component.operaterLog.OperateLogInfo");
attribute.setOperater(s);
attribute.setModule(menu.replaceAll("[]\\[]",""));
// log.debug("解析代理系统操作日志{},耗时{}, OperateLogInfo:{}" , name, System.currentTimeMillis() - sTime,attribute.getOperationType());
}
} catch (Exception ex) {
log.error("为防止意外捕获一下,打印参数不可能出错的{}",ex);
}
// 导出限制
ExportLimit exportLimitAnnotation = method.getAnnotation(ExportLimit.class);
if(Objects.nonNull(exportLimitAnnotation)) {
exportLimit();
}

QueryCache queryCacheAnnotation = method.getAnnotation(QueryCache.class);
Object proceed;
if(Objects.nonNull(queryCacheAnnotation)){
proceed = cachedata(pjp,name,url,queryCacheAnnotation);
}else{
proceed = pjp.proceed();
}
if(Objects.nonNull(exportLimitAnnotation)) {
// 删除缓存
RedisUtils.getRedisTemplate().delete(StrUtil.format(Common.EXPERT_LIMIT_LOCK_SITE_KEY, HttpUtils.getSizeId()));
}
try {
long time = System.currentTimeMillis() - start;
String requestId = MDC.get("requestId");
CompletableFuture.runAsync(()->{
MDC.put("requestId", requestId);
long start1 = System.currentTimeMillis();
String s = JSON.toJSONString(proceed, new SimpleValueFilter());
int endIndex = s.length();
if(endIndex > respParameterLength){
endIndex = respParameterLength;
s = s.substring(0,endIndex)+"...";
}
log.info("controller执行{},返回数据:{},耗时{}", name,s,System.currentTimeMillis() - start1);
});
log.info("controller执行结束{},耗时{}", name,time);
} catch (Exception e) {
log.error("打印响应参数出错",e.getMessage());
}
return proceed;
}

private Object cachedata(ProceedingJoinPoint pjp, String name, String url, QueryCache annotation) throws Throwable {
HttpServletResponse response = HttpUtils.getResponse();
Object proceed;//过期时间
try {
String apolloKey = annotation.value();
if (StrUtil.isBlank(apolloKey)) {
apolloKey = name;
}
String property = environment.getProperty(apolloKey);
long expiration = Convert.toLong(property, annotation.timeoutFlag()?annotation.timeout():defaultCacheTime);
if (false) {
response.setStatus(HttpStatus.NOT_MODIFIED.value());
proceed = null;
} else {
Object[] args = pjp.getArgs();
String redisKey = apolloKey;
if (args.length > 0) {
Field[] fields = ReflectUtil.getFields(args[0].getClass());
Map<String, String> param = new TreeMap<>();
for (Field field : fields) {
Object fieldValue = ReflectUtil.getFieldValue(args[0], field);
if (fieldValue != null) {
if (fieldValue instanceof String) {
if (!((String) fieldValue).equals("")) {
param.put(field.getName(), fieldValue.toString());
}
} else {
param.put(field.getName(), fieldValue.toString());
}
}

}
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : param.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
if (sb.length() > 0) {
apolloKey += ":" + MD5Util.getMD5(sb.toString());
log.info("生成缓存key={},md5={}", sb.toString(), apolloKey);
}
SessionUser user = userContext.getUser();
redisKey = StrUtil.format("{}:nosyncno_{}", user.getUserName(), apolloKey);
//redisKey = StrUtil.format("{}:nosyncno_{}", HttpUtils.getUser().getName(), apolloKey);
}
//读取redis中的缓存数据
//redis 全路径kc:1:kkcloud-agent-client:webRoot:MemberController.queryMemberList:30E7E8A398973117F99BDF8D17E09374
Object value = redisService.getValue(redisKey);
if (value != null) {
log.info("读取缓存数据url={}",url);
proceed = JSONObject.parseObject(value.toString(), ResponseVO.class);
} else {
proceed = pjp.proceed();
SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
serializeConfig.put(Long.class, ToStringSerializer.instance);
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
redisService.setValue(redisKey, JSON.toJSONString(proceed, serializeConfig,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.IgnoreNonFieldGetter), expiration);
}
}
response.setHeader("last-modified", CommonDateUtil.nowStr());
} catch (Exception ex) {
log.error("读取缓存数据失败{},实时查询数据", ex.getMessage());
proceed = pjp.proceed();
}
return proceed;
}

private void exportLimit() {
int siteId = HttpUtils.getSizeId();
log.info("exportLimit siteId:", siteId);
Boolean result = RedisUtils.setIfAbsent(StrUtil.format(Common.EXPERT_LIMIT_LOCK_SITE_KEY, siteId), "1", expertLimitTime);
if (!result) {
throw new ServiceException(CommonStatusCode.FAILURE.getCode(), "有导出任务正在进行中,请稍后重试");
}
}
}