我正在开发一个Java企业应用程序,目前正在进行Java EE安全性方面的工作,以限制特定用户对特定功能的访问。我已经配置了应用程序服务器和所有内容,现在我正在使用RolesAllowed注释来保护方法:
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface RolesAllowed {
String[] value();
}
当我使用如下注释时,它能很好地工作:
@RolesAllowed("STUDENT")
public void update(User p) { ... }
但这不是我想要的,因为我必须在这里使用一个字符串,重构变得困难,并且可能会出现拼写错误。因此,我想使用枚举值作为此注释的参数。该枚举如下:
public enum RoleType {
STUDENT("STUDENT"),
TEACHER("TEACHER"),
DEANERY("DEANERY");
private final String label;
private RoleType(String label) {
this.label = label;
}
public String toString() {
return this.label;
}
}
所以我尝试将枚举作为参数使用,就像这样:
@RolesAllowed(RoleType.DEANERY.name())
public void update(User p) { ... }
但是,我得到了以下编译器错误,尽管Enum.name只返回一个字符串(这个字符串总是常量,不是吗?)。
注释属性RolesAllowed.value的值必须是一个常量表达式。
接下来,我尝试向我的枚举类中添加一个额外的final字符串。
public enum RoleType {
...
public static final String STUDENT_ROLE = STUDENT.toString();
...
}
但是这也不能作为参数,会导致相同的编译错误:
// The value for annotation attribute RolesAllowed.value must be a constant expression
@RolesAllowed(RoleType.STUDENT_ROLE)
我应该如何实现我想要的行为?我甚至实现了自己的拦截器来使用我的注解,这很美妙,但对于这样一个小问题而言,代码行数太多了。
免责声明
这个问题最初是一个Scala问题。我发现Scala不是问题的源头,所以我首先尝试在Java中解决它。