最近,我对JSR-269注释处理感兴趣,我想编写一个lib来消除一些样板代码,例如json处理。我确实生成了代码,但是然后,我遇到了一个致命问题,花了很多时间,但无法解决它。
问题是,该RoundEnvironment.getElementsAnnotatedWith()
方法总是返回所有带有注释的元素,我无法确定哪个是来自特定类的。也许问题还不清楚。我向您展示下面的代码。
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface JsonObject {
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface JsonField {
String value() default "";
}
@JsonObject
public class Name {
@JsonField("last") public String last;
@JsonField("first") public String first;
}
@JsonObject
public class User {
@JsonField("age") public int age;
@JsonField("name") public String name;
@JsonField("sex") public boolean sex;
}
第一个2是注释,JsonObject
指示带注释的类型是JsonObject,并且JsonField
指示带注释的字段是json字段。
后两个是我想要粘贴json-parse代码的示例POJO类。
在Processor
该类的AbstractProcessor.process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
方法中,当我循环调用roundEnv.roundEnv.getElementsAnnotatedWith(JsonField.class)
每个type(Name
,User
)时,返回结果是所有json字段,在上面的示例中,结果是[“ last”,“ first”,“ age”,“名称”,“性别”]。在这种情况下,我无法区分哪个字段属于哪个POJO。
可能是这些词无法解释我的意思。这是我在process
方法中所做的。
// the set[Name, User]
Set<? extends Element> jsonObjects = roundEnv.getElementsAnnotatedWith(JsonObject.class);
for (Element jsonObject : jsonObjects) {
// the set[last, first, age, name, sex], **THIS IS THE PROBLEM**
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(JsonField.class);
// other stuff...
}
随意问我任何我未提及或不清楚的内容。任何建议表示赞赏,在此先感谢!
您可以通过调用getElementsAnnotatedWith(JsonField.class)
方法并根据封闭元素的注释对结果进行过滤,来构建json对象元素的集合。
这是一个完整的示例(为简单起见,使用运行时批注处理):
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes("*")
public class ElementFilterProcessor extends AbstractProcessor {
@Retention(RetentionPolicy.RUNTIME)
public static @interface JsonObject {}
@Retention(RetentionPolicy.RUNTIME)
public static @interface JsonField { String value(); }
@JsonObject
public class Name {
@JsonField("last") public String last;
@JsonField("first") public String first;
}
@JsonObject
public class User {
@JsonField("age") public int age;
@JsonField("name") public String name;
@JsonField("sex") public boolean sex;
}
public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final JavaCompiler.CompilationTask task = compiler.getTask(
null,
null,
null,
null,
Collections.singleton(ElementFilterProcessor.class.getName()),
Collections.EMPTY_SET);
task.setProcessors(Collections.singleton(new ElementFilterProcessor()));
task.call();
}
@Override
public boolean process(
final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return true;
}
final Set<? extends Element> jsonFields =
roundEnv.getElementsAnnotatedWith(JsonField.class);
final Map<Element, List<Element>> jsonObjects = new HashMap<>();
for (final Element element : jsonFields) {
final Element classElement = element.getEnclosingElement();
if (classElement.getAnnotation(JsonObject.class) != null) {
List<Element> list = jsonObjects.get(classElement);
if (list == null) {
list = new ArrayList<>();
jsonObjects.put(classElement, list);
}
list.add(element);
}
}
System.out.println(jsonObjects);
return false;
}
}
输出:
{stackoverflow.annotation.ElementFilterProcessor.User=[age, name, sex], stackoverflow.annotation.ElementFilterProcessor.Name=[last, first]}
我还建议您考虑使用第三方库将Java对象映射到JSON。例如,杰克逊处理器
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句