問題描述
我正在開發一個 Java 企業應用程序,目前正在做 Java EE 安全工作,以限制特定用戶對特定功能的訪問.我配置了應用程序服務器和所有內容,現在我使用 RolesAllowed-annotation 來保護方法:
I'm developing a Java enterprise application, currently doing Java EE security stuff to restrict access for particular functions to specific users. I configured the application server and everything, and now I'm using the RolesAllowed-annotation to secure the methods:
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface RolesAllowed {
String[] value();
}
當我像這樣使用注釋時,它工作正常:
When I use the annotation like this, it works fine:
@RolesAllowed("STUDENT")
public void update(User p) { ... }
但這不是我想要的,因為我必須在這里使用字符串,重構變得困難,并且可能會發生拼寫錯誤.因此,我不想使用字符串,而是使用枚舉值作為此注釋的參數.枚舉看起來像這樣:
But this is not what I want, as I have to use a String here, refactoring becomes hard, and typos can happen. So instead of using a String, I would like to use an Enum value as a parameter for this annotation. The Enum looks like this:
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;
}
}
所以我嘗試使用 Enum 作為這樣的參數:
So I tried to use the Enum as a parameter like this:
@RolesAllowed(RoleType.DEANERY.name())
public void update(User p) { ... }
然后我得到以下編譯器錯誤,盡管 Enum.name 只返回一個字符串(它始終是常量,不是嗎?).
But then I get the following compiler error, although Enum.name just returns a String (which is always constant, isn't it?).
注解屬性RolesAllowed.value的值必須是常量表達式`
The value for annotation attribute RolesAllowed.value must be a constant expression`
接下來我嘗試在我的枚舉中添加一個額外的最終字符串:
The next thing I tried was to add an additional final String to my Enum:
public enum RoleType {
...
public static final String STUDENT_ROLE = STUDENT.toString();
...
}
但這也不能作為參數起作用,導致同樣的編譯器錯誤:
But this also doesn't work as a parameter, resulting in the same compiler error:
// The value for annotation attribute RolesAllowed.value must be a constant expression
@RolesAllowed(RoleType.STUDENT_ROLE)
如何實現我想要的行為?我什至實現了自己的攔截器來使用自己的注釋,這很漂亮,但是對于這樣的小問題,代碼行數太多了.
How can I achieve the behavior I want? I even implemented my own interceptor to use my own annotations, which is beautiful, but far too much lines of codes for a little problem like this.
免責聲明
這個問題最初是一個 Scala 問題.我發現 Scala 不是問題的根源,所以我首先嘗試在 Java 中執行此操作.
This question was originally a Scala question. I found out that Scala is not the source of the problem, so I first try to do this in Java.
推薦答案
我認為您使用枚舉的方法行不通.我發現如果我將最后一個示例中的 STUDENT_ROLE
字段更改為常量字符串,而不是表達式,編譯器錯誤就會消失:
I don't think your approach of using enums is going to work. I found that the compiler error went away if I changed the STUDENT_ROLE
field in your final example to a constant string, as opposed to an expression:
public enum RoleType {
...
public static final String STUDENT_ROLE = "STUDENT";
...
}
但是,這意味著枚舉值不會在任何地方使用,因為您將在注釋中使用字符串常量.
However, this then means that the enum values wouldn't be used anywhere, because you'd be using the string constants in annotations instead.
在我看來,如果你的 RoleType
類只包含一堆靜態的 final String 常量,你會做得更好.
It seems to me that you'd be better off if your RoleType
class contained nothing more than a bunch of static final String constants.
要了解您的代碼未編譯的原因,我查看了 Java 語言規范 (JLS).annotations 的 JLS 聲明對于注釋帶有 T 類型的參數和值 V,
To see why your code wasn't compiling, I had a look into the Java Language Specification (JLS). The JLS for annotations states that for an annotation with a parameter of type T and value V,
如果T 是原始類型或String
,則V 是常量表達式.
if T is a primitive type or
String
, V is a constant expression.
常量表達式包括,其中其他的,
TypeName 形式的限定名稱.標識符表示常量變量
Qualified names of the form TypeName . Identifier that refer to constant variables
并且定義了一個常量變量作為
原始類型或 String
類型的變量,它是最終的并使用編譯時常量表達式進行初始化
a variable, of primitive type or type
String
, that is final and initialized with a compile-time constant expression
這篇關于使用 Enum 類型作為 @RolesAllowed-Annotation 的值參數的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!