Получение списка настроенных действий в 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
Он дает вам точную информацию, которую вы ищете: действия, методы, результаты, параметры, сопоставления и т. Д., И выглядит это так: