Получение списка настроенных действий в Struts2

В проекте, использующем Struts2 (2.3.20), я хотел бы запускать настроенные действия (имя, класс, пространство имен, метод) при запуске приложения.

я использую

  • Struts 2.3.20
  • распорки-весна-плагин
  • распорки конвенционный-плагин

Для справки: я уже проделал некоторую работу с бобами и инжекцией Struts, поэтому пока не совсем в курсе, но я застрял в решении указанной здесь проблемы

Любые указатели о том, как получить это будет оценено.

Дальнейшее объяснение

Читая ответ Андреа ниже, я вижу, что мне нужно объяснить, что мне нужно.

Я строю функцию построителя меню приложения для приложения. Мой план состоит в том, чтобы получить конфигурации действий и построить дерево "узлов меню" из информации в аннотациях по выбранным классам действий и методам.

Моя проблема с кодом из конфиг-браузера заключается в том, что Configuration (xwork) не доступен вне компонентов Struts. Поскольку это задача запуска приложения, она не совсем подходит для модели компонентов MVC Struts. Я хотел бы поместить инициализацию здания меню в ServletContextListener,

Поддельный пример

Для каждого запроса здесь есть только actionconfig соединения <-> аннотация <-> my_custom_menu. Из этого я мог бы создать структуру меню из аннотаций к классам действий и методам.

public class ActionMenuBuilderListener implements ServletContextListener {
  @Override
  public void contextInitialized(ServletContextEvent arg0) {
    List<ActionCfg> actions = Struts.getConfiguredActions(); // thisi is where I'd like some help
    for(ActionCfg action : actions) {
      MenuAnnotation annotation = getAnnotationFromMethodOrClass(action);
      if(annotation != null) {
        addMenuItem(action, annotation);
      }
    }
  }
}

Вот ActionCfgэто то, что класс Struts вернул бы для конфигурации действий, Struts.getConfiguredActions() будет один или несколько вызовов компонентов Struts и addMenu(...) где я добавляю узел пункта меню в мою структуру. Позднее структура является целью от JSP для создания меню.

Я не знаю, сколько еще кода написать.

Мое решение

Для полноты я думал, что я включу, что из этого получилось.

Во-первых, я подключился к Struts через этоServletContextListnere:

public class ActionMenuBuilderListener implements
    ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent arg0) {
}

@Override
public void contextInitialized(ServletContextEvent event) {

    ActionMenuDispatcherListener listener =
    new ActionMenuDispatcherListener(); 
    ServletContext context = event.getServletContext();
    listener.setServletContext(context);

    Dispatcher.addDispatcherListener(listener);

}
}

Затем я написал DispatcherListener:

public class ActionMenuDispatcherListener implements DispatcherListener {

private ServletContext servletContext;

...

@Override
public void dispatcherInitialized(Dispatcher dispatcher) {

    Map<String, PackageConfig> packages = dispatcher
        .getConfigurationManager().getConfiguration()
        .getPackageConfigs();

    Map<String, Map<String, ActionConfig>> runtimeActionConfigs = dispatcher
        .getConfigurationManager().getConfiguration()
        .getRuntimeConfiguration().getActionConfigs();

    for (String packageKey : runtimeActionConfigs.keySet()) {

    Map<String, ActionConfig> actionConfigs = runtimeActionConfigs
        .get(packageKey);

    for (String actionKey : actionConfigs.keySet()) {
        ActionConfig actionConfig = actionConfigs.get(actionKey);
        PackageConfig packageConfig = packages.get(actionConfig
            .getPackageName());

        if (packageConfig != null) {
        String actionName = actionConfig.getName();
        String namespace = packageConfig.getNamespace();
        try {

            ActionMenu methodAnnotation = getMethodAnnotation(actionConfig);

            if (methodAnnotation != null) {
            String annotationInfo = methodAnnotation.value();
            log.debug("[{}, {}, {}]", namespace, actionName,
                annotationInfo);
            }

        } catch (ClassNotFoundException e) {
            log.error("{}: {}", e.getClass().getSimpleName(),
                e.getMessage());
        }
        }
    }
    }
}

protected ActionMenu getMethodAnnotation(ActionConfig actionConfig)
    throws ClassNotFoundException {
    String className = actionConfig.getClassName();
    String methodName = actionConfig.getMethodName();
    Class<?> actionClass = Class.forName(className);
    try {
    Method method = actionClass.getDeclaredMethod(methodName, null);
    ActionMenu annotation = method.getAnnotation(ActionMenu.class);
    return annotation;
    } catch (NoSuchMethodException | SecurityException e) {
    // log.error("{}: {}", e.getClass().getSimpleName(),
    // e.getMessage());
    }
    return null;
}

}

На всякий случай, если кто-то еще думает в том же духе:)

2 ответа

Решение

Прежде всего, вам нужно подключиться к процессу инициализации приложения после загрузки и анализа конфигураций. Одним из способов является реализация DispatcherListener который нужно добавить в Dispatcher, Это вы можете сделать в ServletContextListener#contextInitialized метод.

Вторая часть головоломки - получить конфигурации действий. Это довольно просто, потому что экземпляр Dispatcher передается в качестве аргумента в dispatcherInitialized метод. Чтобы получить все текущие конфигурации действий, получите RuntimeConfiguration который содержит данные в Map<String, Map<String, ActionConfig>>где первый ключ карты - это пространство имен пакета, второй ключ карты - это имя действия и ActionConfig содержит всю информацию о действии. Так как вам нужно имя класса, используйте getClassName() метод этого.

public class ActionMenuBuilderListener implements ServletContextListener,DispatcherListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        Dispatcher.addDispatcherListener(this);
    }

    @Override
    public void dispatcherInitialized(Dispatcher du) {
        Map<String, Map<String, ActionConfig>> runtimeActionConfigs = du
            .getConfigurationManager().getConfiguration().getRuntimeConfiguration()
            .getActionConfigs();
    }
    // other methods
}

И, конечно же, не забудьте зарегистрировать слушателя в web.xml.

Вы свободны строить эту вещь для своего личного роста, но будьте осторожны, что она уже существует.

Он называется Config Browser Plugin (struts2-config-browser-plugin-2.3.20.jar).

Он включен по умолчанию в архетипы Maven, и вы должны помнить об удалении его перед началом работы.

После импорта он доступен по адресу:

//www.SERVER_NAME.com:8080/WEBAPP_NAME/config-browser / actionNames

Он дает вам точную информацию, которую вы ищете: действия, методы, результаты, параметры, сопоставления и т. Д., И выглядит это так:

введите описание изображения здесь

Другие вопросы по тегам