=Start=
缘由:
前段时间事情太多,没时间去维护博客,间断了快一个月,最近稍微好了一些,重新开始整理记录,记录分享的好习惯还是要保持,否则时间也很可能被浪费去刷手机了……
这里简单整理记录一下如何提取Java文件中的类名、方法名、接口名等信息的方法。最容易想到的有一种方法是借助正则表达式进行提取,不过这对Java文件的内容格式有一定要求,且准确率会有天然的天花板在那(非语义程度,仅当成字符串处理,误报不可避免);另一种方式就是利用一些AST的解析器来实现,这里要介绍的也是这种,方便以后需要的时候使用。
正文:
参考解答:
大致思路或方法其实就是继承某个Visitor(比如这里的:VoidVisitorAdapter)覆写其中的visit方法,添加打印或是其它的一些自定义功能。
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.google.common.base.Strings;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import static com.github.javaparser.StaticJavaParser.parse;
public class JavaParserListFileClassNames {
public void listClasses(File projectDir) {
new DirExplorer((level, path, file) -> path.endsWith(".java"), (level, path, file) -> {
System.out.println(path);
System.out.println(Strings.repeat("=", path.length()));
try {
new VoidVisitorAdapter<Object>() {
@Override
public void visit(ClassOrInterfaceDeclaration n, Object arg) {
super.visit(n, arg);
System.out.println(" * " + n.getName());
}
@Override
public void visit(MethodDeclaration n, Object arg) {
super.visit(n, arg);
System.out.println(" -> " + n.getName());
}
}.visit(parse(file), null);
System.out.println(); // empty line
} catch (IOException e) {
new RuntimeException(e);
}
}).explore(projectDir);
}
private static String parseClassname(File filename) throws Exception {
try (FileInputStream fin = new FileInputStream(filename)) {
CompilationUnit cu = parse(fin);
VoidVisitor<?> methodNameVisitor = new MethodNamePrinter();
methodNameVisitor.visit(cu, null);
for (TypeDeclaration type : cu.getTypes()) {
// System.out.println(type.getFullyQualifiedName().toString());
if (type instanceof ClassOrInterfaceDeclaration)
return type.getNameAsString();
}
// for (Node node: cu.getChildNodes()) {
// System.out.println(node);
// System.out.println(node.getAllContainedComments());
// }
}
return null;
}
public static void main(String[] args) {
File projectDir = new File("/path/to/FileName.java");
JavaParserListFileClassNames javaParserListFileClassNames = new JavaParserListFileClassNames();
try {
System.out.println(javaParserListFileClassNames.parseClassname(projectDir));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
projectDir = new File("/path/to/dir");
javaParserListFileClassNames.listClasses(projectDir);
}
private static class MethodNamePrinter extends VoidVisitorAdapter<Void> {
@Override
public void visit(MethodDeclaration md, Void arg) {
super.visit(md, arg);
System.out.println("Method Name Printed: " + md.getName());
}
}
}
参考链接:
https://github.com/javaparser/javaparser
http://javaparser.org/getting-started.html
https://leanpub.com/javaparservisited
Getting started with JavaParser: analyzing Java Code programmatically(时间太久,版本太老,接口已更新,原有代码不可直接用,不过思路可以参考(简单改改内容也基本可用))
https://tomassetti.me/getting-started-with-javaparser-analyzing-java-code-programmatically/
Some examples of code extracting information from Java source files using JavaParser
https://github.com/ftomassetti/analyze-java-code-examples
https://github.com/javaparser/javaparser/issues/2181
=END=
《“使用 JavaParser 解析提取Java文件中的class/method/interface名称”》 有 1 条评论
JavaParse(AST)获取Java Web API list
https://mp.weixin.qq.com/s/ATpoEN9QI-D5vkxDimQ8FQ
`
0x01 目标
目标:将代码中的WebAPI解析出来
0x02 效果
解析完成后的效果大致是这样的,然后在针对要筛选的条件,对api进行筛选即可,例如 RequestMapping等
0x03 代码实现
Gist: https://gist.github.com/B1ueB0ne/7ee600305364f76bf5105c98054f62e6
0x04 parse方法详解
com.github.javaparser.JavaParser#parse
com.github.javaparser.JavaParser#simplifiedParse
com.github.javaparser.JavaParser#CompilationUnit
`