Есть ли способ перенаправить на другой класс действий без использования 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. В этом случае вы можете написать перехватчик вместо фильтра. В основном это будет то же самое, но перехватчик может быть настроен вместе с остальной конфигурацией стоек.