Используйте Перечислимый тип в качестве параметра, передаваемого по значению для @RolesAllowed-Annotation

Я разрабатываю корпоративное приложение 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 атрибута аннотации должно быть константным выражением'

Следующая вещь, которую я попробовал, состояла в том, чтобы добавить дополнительную заключительную Строку к моему Перечислению:

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.

55
задан Reinstate Monica - M. Schröder 31 July 2015 в 00:10
поделиться

1 ответ

Я не думаю, что ваш подход к использованию перечислений сработает. Я обнаружил, что ошибка компилятора исчезла, если я изменил поле STUDENT_ROLE в вашем последнем примере на постоянную строку, а не на выражение:

public enum RoleType { 
  ...
  public static final String STUDENT_ROLE = "STUDENT";
  ...
}

Однако это означает, что значения перечисления не будут можно использовать где угодно, потому что вместо этого вы будете использовать строковые константы в аннотациях.

Мне кажется, вам было бы лучше, если бы ваш класс RoleType содержал не что иное, как набор статических констант final String.


Чтобы понять, почему ваш код не компилируется, я изучил Спецификацию языка Java (JLS). JLS для аннотаций утверждает, что для аннотации с параметром типа T и значением V ,

если T является примитивный тип или String , V является константным выражением.

Постоянное выражение включает, среди прочего,

полные имена в форме TypeName . Идентификатор , который ссылается на постоянные переменные

и постоянную переменную , определяется как

переменная примитивного типа или типа Строка , которая является окончательной и инициализируется выражением константы времени компиляции

31
ответ дан 7 November 2019 в 07:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: