Как настроить Struts 2 для поиска «результатов действий» из classpath и WEB-INF? - PullRequest
5 голосов
/ 01 июня 2011

Фон

У нас есть существующее веб-приложение, построенное на основе Struts 2 и Freemarker, вариант которого я создал, скопировав часть кода и шаблонов. Клудги, но управляемы. Однако вскоре мы сделаем еще несколько вариантов (которые должны быть отдельными WAR-ами), что сделает копирование неприемлемым. Моя мысль - вместо этого поместить все общие материалы в jar, включенный в каждое веб-приложение: общие файлы можно хранить в одном месте, и даже лучше, если данное веб-приложение может переопределять файлы из classpath. До сих пор мне удавалось сделать это с помощью кода, но плагин Convention затрудняет то же самое для шаблонов Freemarker.

Задача

До сих пор наше веб-приложение полагалось на конвенцию, чтобы найти «результаты действий» Freemarker (т.е. шаблоны) для действий при запуске приложения, избавляя нас от необходимости утомительно комментировать каждое из них. Если я все правильно отследил, класс DefaultResultMapBuilder отвечает за поиск результатов действий; в частности, метод createFromResources ищет в веб-приложении, а затем в пути к классам файлы шаблонов, соответствующие нашим действиям.

Это именно то, что я хочу - за исключением того, что мы помещаем наши шаблоны в /WEB-INF, чтобы защитить их от внешнего доступа (используя константу struts.convention.result.path в нашей конфигурации Struts). До сих пор это работало нормально, со ВСЕМИ файлами шаблонов, расположенными в /WEB-INF, но не работает и с файлами, находящимися в пути к классам. DefaultResultMapBuilder может конечно находить файлы в пути к классам, но только когда шаблоны веб-приложений находятся непосредственно в корневом каталоге контекста, поскольку любые шаблоны путей к классам должны быть в структуре пакета, эквивалентной структуре каталогов шаблонов в корневом каталоге контекста. Для получения результатов действия, когда «struts.convention.result.path» начинается с «/ WEB-INF /», потребуется корневой пакет с именем «web-inf», но, конечно, дефисы не допускаются в именах пакетов.

(Обратите внимание, что эта проблема не зависит от классов TemplateLoader, которые впоследствии используются для фактического захвата файлов шаблонов. Процесс загрузки легко настраивается для просмотра во многих местах - но приложение никогда не доберется до этого, если «результаты действий» не обнаруживаются при запуске. Было бы хорошо, если бы оба процесса использовали одну и ту же конфигурацию ...)

Решения

Итак ... Я мог бы переместить все наши шаблоны за пределы /WEB-INF, но на самом деле я бы не стал. Или я мог бы предоставить конкретные аннотации для каждого класса действий, и, опять же, я бы предпочел этого не делать (и на самом деле он может страдать от той же проблемы).

Или я мог бы сделать собственную реализацию ResultMapBuilder, скопировав и очень немного изменив DefaultResultMapBuilder (каждый член последнего является частным, поэтому я не могу расширять класс и изменять только соответствующие части - увы!) , а затем выяснить, как переопределить файл конфигурации Struts "struts-plugin.xml" (для изменения bean-компонента org.apache.struts2.convention.ResultMapBuilder), и, таким образом, я смогу получить соглашение об игнорировании "/ WEB-INF" при просмотре пути к классам. Или, может быть, лучше, чтобы всегда указывать путь перед "/ WEB-INF /" при поиске в ServletContext.

Но, может быть, есть более простой способ? Некоторая недокументированная часть магии конфигурации?

...