我正在开发一个Java企业应用程序,目前正在使用Java EE安全性来限制特定用户对特定功能的访问.我配置了应用程序服务器和所有内容,现在我使用RolesAllowed-annotation来保护方法:
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface RolesAllowed {
String[] value();
}
Run Code Online (Sandbox Code Playgroud)
当我使用这样的注释时,它工作正常:
@RolesAllowed("STUDENT")
public void update(User p) { ... }
Run Code Online (Sandbox Code Playgroud)
但这不是我想要的,因为我必须在这里使用String,重构变得困难,并且可能发生拼写错误.因此,我想使用Enum值作为此注释的参数,而不是使用String.Enum看起来像这样:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我尝试使用Enum作为这样的参数:
@RolesAllowed(RoleType.DEANERY.name())
public void update(User p) { ... }
Run Code Online (Sandbox Code Playgroud)
但是后来我得到了以下编译器错误,虽然Enum.name只返回一个String(它总是不变的,不是吗?).
注释属性RolesAllowed.value的值必须是常量表达式`
我尝试的下一件事是在我的枚举中添加一个额外的最终字符串:
public enum RoleType {
...
public static final String STUDENT_ROLE = STUDENT.toString();
...
}
Run Code Online (Sandbox Code Playgroud)
但这也不能作为参数,导致相同的编译器错误:
// The …
Run Code Online (Sandbox Code Playgroud) 以下代码工作正常,其中 PROCESS_UPDATES 是一个常量。
public static final String PROCESS_UPDATES = "ProcessUpdates";
public static final String PROCESS_UPDATES = "ProcessSnapshots";
// etc....
@Produce(uri = "seda:" + MyClass.PROCESS_UPDATES)
protected ProducerTemplate processUpdatesTemplate;
Run Code Online (Sandbox Code Playgroud)
然而,为了避免到处都是十亿个常量字符串,我尝试了一个枚举设计模式。
public enum Route { ProcessUpdates, ProcessSnapshots }
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,我可以写字"seda:" + Route.ProcessSnapshots
,而且看起来更整洁。
然而,我可信赖的测试代码现在失败了,因为注释中的 uri 必须是常量。
@Produce(uri = "seda:" + MyClass.Route.ProcessUpdates) // compiler error
protected ProducerTemplate processUpdatesTemplate;
Run Code Online (Sandbox Code Playgroud)
错误:Attribute value must be constant
。
问题是,Route.ProcessUpdates.toString()
这种“是”常量,但编译器并不这么认为。
我阅读了有关常量和注释的内容,但没有看到任何答案。
那么有没有一种很好的方法可以在java中的编译时从枚举构造一个常量字符串?
感谢您提供任何提示。维京史蒂夫
这是我的注释:
@Target( { ElementType.METHOD } )
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditUpdate
{
Class<?> value();
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式它是好的:
@AuditUpdate(User.class)
void someMethod(){}
Run Code Online (Sandbox Code Playgroud)
但通过这种方式:
private static final Class<?> ENTITY_CLASS = User.class;
@AuditUpdate(ENTITY_CLASS)
void someMethod(){}
Run Code Online (Sandbox Code Playgroud)
我有这个编译错误:
The value for annotation attribute AuditUpdate.value must be a class literal
Run Code Online (Sandbox Code Playgroud)
为什么?那是什么意思?
谢谢.