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

В настоящее время я изучаю Struts 2, и в настоящее время я создаю простое приложение, где непроверенные пользователи перенаправляются на форму входа.

У меня есть форма входа и действие, которое принимает учетные данные пользователей, проверяет их и сохраняет объект User в сеансе, но теперь я пытаюсь предотвратить доступ к страницам до того, как логин произошел, и я пытаюсь это сделать с перехватчиком.

Моя проблема в том, что я написал перехватчик, который проверяет, был ли сохранен пользовательский объект в сеансе, но если он не я хочу перенаправить на страницу входа в систему и не могу найти способ сделать это без обхода строк и используя метод HttpServletResponse.sendRedirect

Конфигурация:

<package name="mypackage" extends="struts-default" namespace="/admin">

    <interceptors>
        <interceptor name="login" class="my.LoginInterceptor" />
    </interceptors>

    <default-interceptor-ref name="login"/>

    <action name="login" class="my.LoginAction">
        <result name="input">/admin/login.jsp</result>
        <result name="success" type="redirect">/admin</result>
    </action>

    <action name="private" class="my.PrivateAction">
        <result>/admin/private.jsp</result>
    </action>

</package>

Код перехватчика:

@Override
public String intercept(ActionInvocation inv) throws Exception {

    Map<String, Object> session = inv.getInvocationContext().getSession();

    Object user = session.get("user");
    if(user == null) {

                      // redirect to the 'login' action here            

    }
    else {
        return inv.invoke();
    }

}

Ответ 1

Стандартный способ - вернуть специальный глобальный результат (например, "login" ) и определить глобальное сопоставление от этого результата к вашему admin/login.jsp. Поэтому вы просто должны добавить эту строку:

if(user == null) {
      return "login";
}

И в вашем struts.xml:

<global-results>
   <result name="login">/admin/login.jsp</result>
</global-results>

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

<interceptors>
 <interceptor name="login" class="my.LoginInterceptor" />

 <interceptor-stack name="stack-with-login">
  <interceptor-ref name="login"/>
  <interceptor-ref name="defaultStack"/>
 </interceptor-stack>
</interceptors>
<default-interceptor-ref name="stack-with-login"/>

BTW2: Вы НЕ должны применять перехватчик к вашему действию входа, конечно.

Ответ 3

Если вам нужно использовать sendirectirect, верните null, чтобы избежать этой проблемы (например, перенаправление с www.domain.com на domain.com):

public String intercept(final ActionInvocation invocation) throws Exception {

    String url=RequestUtil.getURLWithParams();  //you should implement this
    int index=url.indexOf("www");
    if (index!=-1 && index<10) {
        //Note: <10 to check that the www is in the domain main url
        //https://localhost:8443/mycontext/myaction.action?oneparam=http://www.youtube.com/user/someuser
        String redirection=url.replaceFirst("www\\.", ""); 
        LOG.debug("Redirection from "+url+" to "+redirection);
        RequestUtil.getResponse().setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
        RequestUtil.getResponse().sendRedirect(redirection);
        return null;
    }
    return invocation.invoke();
}