2014-12-15 2 views
0

Я пытаюсь создать URL-адреса, которые выглядят как http://localhost:8080/app/client/shared-namespaces-and-actions:Переменная при запуске пространства имен (или эквивалент)

  • «/app» будет контекст корень.
  • «client» фактически будет переменной, замененной фактической клиентской версией/интерфейсом приложения, например «john» (то есть: http://localhost:8080/app/john/namespaces-and-actions).
  • «/shared-namespaces-and-actions» будут пакеты/действия , доступные под одним или несколькими клиентами (например, «/ about/contact», или «/ products/73/edit»).

В идеале URL-адрес может полностью опустить компонент «клиент», и поэтому для действий, где это имеет смысл, может отображаться какой-то комбинированный вид. Например, «/app/» будет отображать ссылки на клиентские версии, тогда как «/app/client/» клиента будет иметь то, что хочет клиент на своей домашней странице.

Этот переменный компонент «клиент» - это то, о чем я задаю.

До сих пор я использовал параметр строки запроса, чтобы обрабатывать выбор клиента, а не часть пути URL. Однако у этого есть некоторые очевидные проблемы для таких вещей, как закладки, поскольку мне всегда приходится передавать клиентский параметр в строке запроса (не привлекательно), иначе закладки будут терпеть неудачу.

Есть ли простой способ сделать это изменение? Кажется, что я хочу, это шаблон в пространстве имен, как и в случае с действиями, но документация, похоже, не поддерживает это как возможность и не экспериментирует. Я уже использую пакеты для установки пространств имен, стеков перехватчиков и группировки связанных действий в файле struts.xml, поэтому было бы тривиально изменять все действия, находящиеся в пакете пространства имен «/», с дополнительным шаблоном для клиента.

Вариант, на который я смотрел, состоял в том, чтобы расширить класс DefaultActionMapper и переопределить метод parseNameAndNamespace(String, ActionMapping, ConfigurationManager), удалив клиентский компонент URI (если он существует), а затем передав этот модифицированный URI родительской реализации. Однако у этого есть ряд проблем, таких как нарушение всех ссылок, формирование целей и перенаправление. Я ожидаю, что исправление ссылок/форм будет раздражать, чтобы исправить, но не невозможно, но я не уверен, что то же самое относится к перенаправлению.

Я пользуюсь 2.3.16.3.


struts.xml:

<struts> 
    <constant name="struts.enable.SlashesInActionNames" value="true" /> 
    <constant name="struts.mapper.alwaysSelectFullNamespace" value="false" /> 
    <constant name="struts.patternMatcher" value="namedVariable"/> 

    <constant name="struts.action.extension" value="" /> 

    <package 
     name="poc-default" 
     extends="struts-default" 
     strict-method-invocation="true"> 
     <default-interceptor-ref name="defaultStack" /> 
     <default-action-ref name="http404" /> 
     <action 
      name="http404" 
      class="poc.DefaultAction"> 
      <result name="success">/WEB-INF/http404.jsp</result> 
     </action> 
    </package> 

<package 
    name="root" 
    namespace="/" 
    extends="poc-default" 
    strict-method-invocation="true"> 
    <action 
     name="" 
     class="poc.DefaultAction"> 
     <result name="success">/WEB-INF/home.jsp</result> 
    </action> 
    <action 
     name="clients" 
     class="poc.DefaultAction"> 
     <result name="success">/WEB-INF/client-select.jsp</result> 
    </action> 
</package> 
</struts> 

Используя struts.xml выше, "http://localhost:8080/poc/" переходит на главную страницу, и "http://localhost:8080/poc/clients" переходит на страницу выбора клиента.

я затем заменить пакет «корень» со следующим (добавленным именем шаблона в пространстве имен):

<package 
    name="root" 
    namespace="/{uriClientString}/" 
    extends="poc-default" 
    strict-method-invocation="true"> 
    <action 
     name="" 
     class="poc.DefaultAction"> 
     <result name="success">/WEB-INF/home.jsp</result> 
    </action> 
    <action 
     name="clients" 
     class="poc.DefaultAction"> 
     <result name="success">/WEB-INF/client-select.jsp</result> 
    </action> 
</package> 

Теперь, ни действие отображается с помощью URL-адресов «http://localhost:8080/poc/john/» и «http://localhost:8080/poc/john/clients».

+0

Если вы знакомы с подстановочным картографированием, почему вы спросили об этом? –

+0

@RomanC Я знаком с подстановочным сопоставлением имен действий, но не с пространствами имен пакетов, я не видел никаких документов, указывающих, что это возможно, и моя попытка вставить подстановочный знак в пространство имен не удалась. Я надеюсь, что вам не придется сглаживать все мои пакеты в один пакет, причем каждое имя действия дублирует то, что имеет его текущее пространство имен пакетов в отношении пути, просто чтобы получить подстановочные знаки в начале пути (пространство имен) вместо " end "(название действия). Поэтому я надеюсь, что есть какой-то способ иметь подстановочный знак/переменную в/перед пространством имен. – Matt

+0

Вы должны отправить код, который вы пробовали, и ошибки. –

ответ

0

Дав комментарий Дэйва Ньютона, некоторые мысли, я считаю, что он прав, что я собираюсь решить мою проблему (дополнительный префикс выбора клиента для URL), вероятно, не так, как я должен это делать.

Редактирование URL-адресов представляется лучшим (и возможным) выбором и вместо этого помещает клиента в контекст через атрибут запроса. Я создал фильтр, который появляется перед 2 фильтра Strut в web.xml:

@Override 
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) 
     throws ServletException, IOException { 
    final HttpServletRequest httpRequest = (HttpServletRequest) request; 
    final String requestServletPath = httpRequest.getServletPath(); 

    // Obtain set of client strings here. 
    final List<String> clients = Arrays.asList("john"); 

    String newServletPath = null; 
    for (String client : clients) { 
     final String toCheck = "/" + client; 
     if (requestServletPath.equals(toCheck) || requestServletPath.startsWith(toCheck + "/")) { 
      /* 
      * Put client into context here, {@link HttpSession#setAttribute(String, Object)} or 
      * {@link ServletRequest#setAttribute(String, Object)}. 
      */ 
      request.setAttribute("uriClientString", toCheck); 
      newServletPath = requestServletPath.substring(toCheck.length()); 
      break; 
     } 
    } 

    if (newServletPath != null) 
     request.getRequestDispatcher(newServletPath).forward(request, response); 
    else 
     chain.doFilter(request, response); 
} 

Также необходимо Struts отображение фильтра 2 для поддержки вперед:

<filter-mapping> 
    <filter-name>struts2</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

К сожалению, необходимо переписать сформированные URL-адреса, чтобы включить префикс клиента, если он используется, так как в противном случае Struts2 просто исходить из фактического пространства имен:

<s:a namespace="%{#request.uriClientString}" action="">Home page</s:a> 

Наконец, также необходимо переписать переадресацию включить префикс клиента, если он используется, так как, еще раз, Struts2 просто исходить из фактического пространства имен:

<action name="re"> 
    <result type="redirectAction"> 
     <param name="namespace">${#request.uriClientString}</param> 
     <param name="actionName">clients</param> 
    </result> 
</action> 

Это не так легко осуществить, как я надеялся, что в самом начале, но похоже, что он удовлетворит мои потребности, когда все будет обновлено.

Я приму это через пару дней, если не предложит ничего лучшего.

Смежные вопросы