一、实现ThreadLocal
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
@RestController
public class StatController {
static Integer c = 0;
/**
* 锁 进行排队
* @throws InterruptedException
*/
synchronized void _add1() throws InterruptedException {
Thread.sleep(100);
c++;
}
synchronized static void addSet(Val<Integer> v){
set.add(v);
}
static ThreadLocal<Val<Integer>> c2 = ThreadLocal.withInitial(()->{
Val<Integer> v = new Val<>();
v.set(0);
//map.put(Thread.currentThread(),v);
//set.add(v);
addSet(v);
return v;
});
static ThreadLocal<Val<Integer>> c1 = new ThreadLocal<Val<Integer>>(){
//可能存在同步问题
@Override
protected Val<Integer> initialValue(){
Val<Integer> v = new Val<>();
v.set(0);
//map.put(Thread.currentThread(),v);
//set.add(v);
addSet(v);
return v;
}
};
/**
* ThreadLocal
* @throws InterruptedException
*/
void _add2() throws InterruptedException {
Thread.sleep(100);
//c1.set(c1.get() + 1);
Val<Integer> v = c1.get();
v.set(v.get() + 1);
}
//static HashMap<Thread, Val<Integer>> map = new HashMap<>();
static HashSet<Val<Integer>> set = new HashSet<>();
@RequestMapping("/start")
private Integer stat(){
//return c1.get();
return set.stream().map(x->x.get()).reduce((a,x)-> a + x).get();
}
@RequestMapping("/add")
private Integer add() throws InterruptedException {
_add2();
return 1;
}
}
public class Val<T> {
T v;
public void set(T _v){
v = _v;
}
public T get(){
return v;
}
}
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
class MyThreadLocal<T> {
static AtomicInteger atomic = new AtomicInteger();
//T value;
Integer threadLocalHash = atomic.addAndGet(0x61c88647);
static HashMap<Thread, HashMap<Integer, Object>> threadLocalMap = new HashMap<>();
synchronized static HashMap<Integer, Object> getMap(){
var thread = Thread.currentThread();
if(!threadLocalMap.containsKey(thread)){
threadLocalMap.put(thread, new HashMap<Integer, Object>());
}
return threadLocalMap.get(thread);
}
protected T initialValue(){
return null;
}
public T get() {
// if(value == null){
// value = initialValue();
// }
// return value;
var map = getMap();
if(!map.containsKey(this.threadLocalHash)){
map.put(this.threadLocalHash, initialValue());
}
return (T) map.get(this.threadLocalHash);
}
public void set(T v){
var map = getMap();
map.put(threadLocalHash, v);
}
}
二、rtrim、ltrim 、防sql注入工具类
public class Str {
public static String ltrim(String s) {
int i = 0;
while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
i++;
}
return s.substring(i);
}
public static String rtrim(String s) {
int i = s.length()-1;
while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
i--;
}
return s.substring(0,i+1);
}
}
public class SQLi {
public static final Pattern whereInEndPattern = Pattern.compile("(where|and|or)\\s+\\S+?\\s+in\\s*\\(?$", Pattern.CASE_INSENSITIVE);
public static final Pattern whereInWithDollarPattern = Pattern.compile("(where|and|or)\\s+\\S+?\\s+in\\s*\\(?\\s*\\$\\{", Pattern.CASE_INSENSITIVE);
public static final Pattern likeEndPatterh = Pattern.compile("\\S+?\\s+like\\s+('|\")%?$", Pattern.CASE_INSENSITIVE);
public static final Pattern orderByOrGroupByEndPattern = Pattern.compile("(group|order)\\s+by\\s*([a-zA-Z0-9_\\-\\(\\)]+,?\\s{0,3}){0,5}$", Pattern.CASE_INSENSITIVE);
public static final Pattern havingEndPattern = Pattern.compile("having\\s*([a-zA-Z0-9_\\-\\(\\)]+,?\\s{0,3}){0,5}$", Pattern.CASE_INSENSITIVE);
public static final Pattern limitEndPattern = Pattern.compile("limit\\s*([a-zA-Z0-9_\\-\\(\\)]+,?\\s{0,3})?$", Pattern.CASE_INSENSITIVE);
public static final Pattern placeholderPattern = Pattern.compile("%(\\d\\$\\d{0,5})?s", Pattern.CASE_INSENSITIVE);
public static final Pattern dollarVarPattern = Pattern.compile("\\$\\{(\\S+?)\\}");
/**
* 判断数组是否有拼接SQL注入风险
* 排除表名,部分字段名情况
* @param fragments List<String>
* @return boolean
*/
public static boolean hasVulOnAdditiveFragments(@NotNull List<String> fragments) {
return fragments.stream()
.map(String::toLowerCase)
.map(String::trim)
.anyMatch(item ->
// group by ${field}
// order by id, ${field}
!(
orderByOrGroupByEndPattern.matcher(item).find() &&
!limitEndPattern.matcher(item).find()
) &&
// having ${field} > 18
!havingEndPattern.matcher(item).find() &&
// from ${table}
!item.endsWith("from") &&
// (inner|outer) join ${table}
!item.endsWith("join") &&
// select ${field}
// select id, ${field}
!(
item.startsWith("select") &&
!item.contains("from")
) &&
// update ${table}
!item.endsWith("update") &&
// update TABLE set ${field}
!(
item.startsWith("update") &&
item.endsWith("set")
) &&
// insert into TABLE(${field})
// insert into TABLE(id, ${field})
!(
item.startsWith("insert into") &&
!item.contains("value")
) &&
// insert into TABLE (${field})
!item.equals("(")
);
}
}