package io.ct.java.agent;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class MyAgent {
public static void premain(String agentArgs, Instrumentation inst) throws Exception {
System.out.println(agentArgs);
//通过引入注解类获取注解所在的类和方法
/* ClassScaner classScaner = new ClassScaner();
HashMap<String, String> map = classScaner.getclass();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+"->"+entry.getValue());
}*/
System.out.println("----------start----------");
/*分割*/
ArrayList<String> list = new ArrayList<>();
String[] split = agentArgs.split("\\?");
String s = split[0];
String replace = s.replace('/', '.');
String[] split1 = split[1].split("&");
for (String s1 : split1) {
list.add(replace+"."+s1);
}
inst.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//对传参进行处理
/*
* 扫描所有的类
* */
for (String s1 : list) {
if(className.contains(s)){
// 获取一个 class 池。
ClassPool classPool = ClassPool.getDefault();
try {
// 创建一个新的 class 类。classfileBuffer 就是当前class的字节码
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtClass cc = classPool.get(s1);
if(cc.isFrozen()){
cc.defrost();
}
//插入集合以及遍历集合
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("java.util.Set/*<java.util.Map.Entry<java.lang.String, java.lang.String[]>>*/ entries = request.getParameterMap().entrySet();");
stringBuffer.append("if (entries.isEmpty()) {System.out.println(\"空\");}");
stringBuffer.append("java.util.Iterator/*<java.util.Map.Entry<java.lang.String, java.lang.String[]>>*/ iterator = entries.iterator();");
stringBuffer.append("while (iterator.hasNext()) {java.util.Map.Entry/*<java.lang.String, java.lang.String[]>*/ next = iterator.next();System.out.println(next.getKey());java.lang.Object value = next.getValue();System.out.println(java.util.Arrays.toString((java.lang.Object[]) value));}");
CtMethod[] personFly = cc.getDeclaredMethods();
for (CtMethod ctMethod : personFly) {
//获取所有的注解
Object[] annotations = ctMethod.getAnnotations();
for (Object annotation : annotations) {
//如果是对应的注解
if (annotation.toString().contains("com.example.agent.annotation.ResMapping")) {
ctMethod.insertBefore("System.out.println(\"所有参数\"+request.getParameterMap());");
// ctMethod.insertBefore("java.util.Set entries = request.getParameterMap().entrySet();");
ctMethod.insertAfter(stringBuffer.toString());
/*Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
System.out.println(entry.getKey()+"->");
String[] value = entry.getValue();
for (String s : value) {
System.out.println(s);
}
}*/
}
}
}
// 返回新的字节码
return ctClass.toBytecode();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return new byte[0];
}
});
}
}
javassist插入集合以及遍历集合
最新推荐文章于 2023-02-27 18:25:40 发布
这篇文章介绍了一个名为MyAgent的Java代理类,它能在运行时扫描传入的类文件,并针对带有特定注解的方法添加参数映射处理。通过ClassFileTransformer接口,MyAgent可以拦截并修改方法调用前后的代码,用于增强或修改参数行为。
摘要由CSDN通过智能技术生成