Есть несколько проблем с кодом, который у вас есть в настоящее время.
- Вы должны использовать Interceptor для обеспечения того, чтобы пользователь вошел в систему, а не пытаться применять его в JSP. JSP должен быть только для представления, а не для управления потоком.
- Вам следует избегать скриптлетов (блоков кода) в JSP. Это устарело очень давно и широко считается очень плохой практикой в приложении MVC.
- Вы можете получить доступ к значениям сеанса непосредственно в вашем JSP. Вам не нужно реализовывать интерфейс
SessionAware
в своем действии, если вам не нужен доступ к сеансу внутри самого действия.
- Вы должны перенаправить пользователя к действию входа в систему, а не непосредственно к странице JSP, в противном случае вы обходите инфраструктуру Struts2 и теряете преимущества ее использования.
Пример входа в систему
Ниже приведен пример кода для создания базовой системы входа в систему с использованием инфраструктуры Struts2.
Требуется вход в систему
Эта часть является необязательной, но, как правило, не все страницы в веб-приложении требуют входа пользователя в систему. Поэтому давайте создадим интерфейс с именем LoginRequired
. Любое действие, реализующее этот интерфейс маркера, будет перенаправлено на страницу входа, если пользователь еще не вошел в систему.
Примечание. Вместо этого вы можете использовать аннотацию, если хотите, но для этого примера я буду использовать интерфейс.
public interface LoginRequired {}
Перехватчик
Перехватчик будет обрабатывать принуждение пользователя войти в систему для любого запрошенного действия, которое реализует интерфейс LoginRequired
.
public class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(final ActionInvocation invocation) throws Exception {
Map<String, Object> session = ActionContext.getContext().getSession();
// sb: feel free to change this to some other type of an object which
// represents that the user is logged in. for this example, I am using
// an integer which would probably represent a primary key that I would
// look the user up by with Hibernate or some other mechanism.
Integer userId = (Integer) session.get("userId");
// sb: if the user is already signed-in, then let the request through.
if (userId != null) {
return invocation.invoke();
}
Object action = invocation.getAction();
// sb: if the action doesn't require sign-in, then let it through.
if (!(action instanceof LoginRequired)) {
return invocation.invoke();
}
// sb: if this request does require login and the current action is
// not the login action, then redirect the user
if (!(action instanceof LoginAction)) {
return "loginRedirect";
}
// sb: they either requested the login page or are submitting their
// login now, let it through
return invocation.invoke();
}
}
Вам также потребуется LoginAction
, который отображает и обрабатывает страницу входа в систему, и LogoutAction
, который делает недействительным или очищает сеанс.
Конфигурация
Вам потребуется добавить перехватчик в ваш стек, а также создать глобальное отображение результатов для «loginRedirect».
<interceptors>
<interceptor name="login" class="your.package.LoginInterceptor"/>
<!-- sb: you need to configure all of your interceptors here. i'm only
listing the one we created for this example. -->
<interceptor-stack name="yourStack">
...
<interceptor-ref name="login"/>
...
</interceptor-stack>
</interceptors>
<global-results>
<!-- sb: make this the path to your login action.
this could also be a redirectAction type. -->
<result name="loginRedirect" type="redirect">/login</url>
</global-results>