有人能说出我的代码出了什么问题吗?当使用javassist插入代码时,它显示错误“原因:编译错误:;缺少”;但我仔细检查了一下,根本没有;缺少。这里的javassist有什么限制吗?
ClassPool cp = ClassPool.getDefault();
cp.importPackage("com.mysql.cj");
CtClass cc = cp.get(clzname);
CtMethod ms = cc.getDeclaredMethod(
"execute");
StringBuilder sb = new StringBuilder();
sb.append("String sql = ((PreparedQuery) this.query).getOriginalSql();");
sb.append("QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();\n" +
" for (BindValue o : bindings.getBindValues()) {\n" +
" sql = sql.replaceFirst(\"\\\\?\", new String(o.getByteValue()));\n" +
" }");
sb.append(
"System.out.println( sql);");
ms.insertBefore(sb.toString());
byteCode = cc.toBytecode();发布于 2020-09-04 16:42:27
insertBefore的javadoc说:
https://www.javassist.org/html/javassist/CtBehavior.html#insertBefore(java.lang.String)
参数: src -表示插入字节码的源代码。它必须是单个语句或块。
所以,把代码放在大括号里,这样它就是一个单独的代码块。
发布于 2020-09-07 11:35:38
我通过替换for循环解决了我的bug。
i<似乎不支持方便for循环,必须将其转换为for(int i= 0;javaassit长度;i++)格式;
多亏了@kutschem,代码还需要用大括号括起来。
ClassPool cp = ClassPool.getDefault();
cp.importPackage("com.mysql.cj");
CtClass cc = cp.get(clzname);
CtMethod ms = cc.getDeclaredMethod(
"execute");
ms.insertBefore("{\n" +
" String sql = ((PreparedQuery) this.query).getOriginalSql();\n" +
" QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();\n" +
" for (int i =0; i < bindings.getBindValues().length; i++ ) sql = sql.replaceFirst(\"\\\\?\", new String(bindings.getBindValues()[i].getByteValue()));\n" +
" System.out.println(sql);\n" +
" }");
byteCode = cc.toBytecode();发布于 2020-09-05 11:44:41
除了像@kutschem说的那样将你的代码包装到大括号中,我还为你提供了一个想法,让你可以更容易地连接字符串,而不需要使用StringBuilder。作为一个积极的副作用,您还会得到换行:
String codeToBeInserted = String.join("\n",
"{",
" String sql = ((PreparedQuery) this.query).getOriginalSql();",
" QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();",
" for (BindValue o : bindings.getBindValues()) {",
" sql = sql.replaceFirst(\"\\\\?\", new String(o.getByteValue()));",
" }",
" System.out.println(sql);",
"}"
);
System.out.println(codeToBeInserted);String.join是从Java8开始提供的。控制台输出将是:
{
String sql = ((PreparedQuery) this.query).getOriginalSql();
QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();
for (BindValue o : bindings.getBindValues()) {
sql = sql.replaceFirst("\\?", new String(o.getByteValue()));
}
System.out.println(sql);
}对我来说,您的代码在语法上看起来还不错,特别是用固定值替换?的replaceFirst。
https://stackoverflow.com/questions/63737553
复制相似问题