Есть ли способ перенаправить на другой класс действий без использования Struts.xml

У меня есть много классов, созданных в моем приложении Struts. Я не проверял, вошел ли в систему состояние ни в одном из классов. Вместо этого я расширил базовый класс действий.

Теперь я хочу создать предварительный обработчик в своем базовом действии, чтобы проверять вход в систему и перенаправлять, если они не вошли в систему. Я хочу что-то вроде этого.

public BaseAction(){
  if(isLoggedIn){
    //go to child which was called
   }
   else {   //redirect to login page
  }

   }

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

<result name="not-logged-in" type="redirectAction">Login.action</result>

Пожалуйста, помогите мне найти лучший способ для этого.

2 ответа

Решение

Похоже, вы хотите проверить в конструкторе базового класса действий, но вы ошибаетесь. Конструктор используется фабрикой объектов для создания экземпляра вашего действия. На этом этапе вам доступно несколько вещей. В твоем случае это неправильно. Другой подход, если вы переместите логику в методе, скажем execute() и позвонить super.execute() до того, как вызов какого-либо метода сработает, но если вы забудете включить супер-вызов в действие, вы можете в конечном итоге запустить код действия без аутентификации. Чтобы предотвратить это, вы должны запустить код до того, как будет выполнено какое-либо действие, и иметь доступ к экземпляру действия или контексту действия, чтобы иметь больше возможностей Struts2. Я полагаю, вы никогда не читали книгу "Struts 2 in Action", поэтому я поделюсь с вами своими мыслями. Это о создании AuthenticationInterceptor и действие, которое реализует UserAware который внедряет пользователя, вошедшего в действие, которое реализует этот интерфейс. Перехватчик выглядит

public class AuthenticationInterceptor implements Interceptor {

public void destroy() {
}

public void init() {
}

public String intercept(ActionInvocation actionInvocation) throws Exception {
    Map session = actionInvocation.getInvocationContext().getSession();
    User user = (User) session.get(Struts2MyConstants.USER);

    if (user == null) {
        return Action.LOGIN; //login required result
    }               
    else {              
        Action action = (Action)actionInvocation.getAction();

        if (action instanceof UserAware) {
            User freshUser = myService.getUser(user.getId());
            ((UserAware)action).setUser(freshUser);
        }

        System.out.println("Logged in: interceptor");
        return actionInvocation.invoke();
    }
}

UserAware это выглядит как

public interface UserAware {

    public void setUser( User user );

}

и создать безопасный стек по умолчанию, который будет ссылаться на любое действие

<interceptors>
  <interceptor name="authenticationInterceptor" class="org.yourapp.struts.interceptor.AuthenticationInterceptor"/>
  <interceptor-stack name="secureStack">
    <interceptor-ref name="authenticationInterceptor"/>
    <interceptor-ref name="defaultStack"/>
  </interceptor-stack>
</interceptors>
<default-interceptor-ref name="secureStack"/> 

Если вы делаете базовое действие для реализации UserAware тогда пользовательский объект, который вошел в систему, будет доступен не только из сеанса, но и в действии, если вы определите для пользователя getter или сделаете его защищенным. Вы должны сделать User объект неизменяемый, чтобы не ставить под угрозу функцию безопасности.

Вы можете использовать Filter, Это будет намного прозрачнее, чем требовать от всех ваших классов продления BaseAction,

редактировать

Вы должны отобразить этот фильтр в файле web.xml, чтобы он выполнялся перед сервлетом контроллера Struts.

<filter>
   <filter-name>AuthorizationFilter</filter-name>
   <filter-class>my.company.AuthorizationFilter</filter-class>
</filter>

<filter-mappging>
    <filter-name>AuthorizationFilter</filter-name>
    <servlet-name>StrutsActionServlet</servlet-name>
</filter-mapping>

Или по шаблону URL:

<filter-mapping>
    <filter-name>AuthorizationFilter</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>

редактировать

Вы изменили вопрос, и кажется, что это все-таки распорки 2. В этом случае вы можете написать перехватчик вместо фильтра. В основном это будет то же самое, но перехватчик может быть настроен вместе с остальной конфигурацией стоек.

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