2014-12-30 7 views
1

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

ContainsKeyInterceptor:

public class ContainsKeyInterceptor extends AbstractInterceptor implements SessionAware { 
    private static final long serialVersionUID = 1L; 

    private Map<String, Object> session; 

    @Override 
    public String intercept(ActionInvocation actionInvocation) throws Exception { 
     if(session == null) { 
      System.out.println("session is null"); 
     } 

     if(session.containsKey("currentId")) { 
      return "index"; 
     } 

     String result = actionInvocation.invoke(); 

     return result; 
    } 

    @Override 
    public void setSession(Map<String, Object> session) { 
     this.session = session; 
    } 
} 

Предполагается перенаправить пользователя на страницу индекса, если currentId находится в session.

Однако, я получаю NullPointerException, заявив, что session имеет значение null, что подтверждено if-check.

struts.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 
    "http://struts.apache.org/dtds/struts-2.3.dtd"> 

<struts> 
    <constant name="struts.devMode" value="false" /> 

    <!-- actions available to guests --> 
    <package name="guest" extends="struts-default"> 
     <interceptors> 
      <interceptor name="containskeyinterceptor" class="com.mypackage.interceptor.ContainsKeyInterceptor" /> 
     </interceptors> 

     <action name="index" class="com.mypackage.action.IndexAction"> 
      <interceptor-ref name="containskeyinterceptor" /> 
      <result type="redirect">/index.jsp</result> 
      <result name="index" type="redirect">/index.jsp</result> 
     </action> 

     <action name="login" class="com.mypackage.action.LoginAction"> 
      <interceptor-ref name="containskeyinterceptor" /> 
      <result type="redirect">/index.jsp</result> 
      <result name="input">/login.jsp</result> 
      <result name="index" type="redirect">/index.jsp</result> 
     </action>  
    </package> 

    <!-- actions available to members --> 
    <package name="member" extends="struts-default"> 
     <action name="logout" class="com.mypackage.action.LogoutAction"> 
      <result type="redirectAction"> 
       <param name="actionName">index</param> 
      </result> 
     </action> 
    </package> 
</struts> 

Почему session утратившим как решить?

(This была ссылка, которую я использовал.)

ответ

2

Стрит Сессия - это всего лишь Map<String,Object>, обертывающий лежащий в основе HttpSession.

При реализации интерфейса SessionAware is the correct way to get it in an Action, если вы хотите получить его изнутри перехватчик, что вам нужно сделать следующее:

Чтобы получить Struts сессии Карта:

@Override 
public String intercept(ActionInvocation ai) throws Exception { 
    final ActionContext context = ai.getInvocationContext(); 

    // Struts Session 
    Map<String, Object> session = context.getSession(); 

Для получить реальный HttpSession объект:

@Override 
public String intercept(ActionInvocation ai) throws Exception { 
    final ActionContext context = ai.getInvocationContext(); 

    HttpServletRequest request = (HttpServletRequest)context.get(StrutsStatics.HTTP_REQUEST); 

    // Http Session 
    HttpSession session = request.getSession(); 

Тем не менее, причина, по которой вы не получаете сессию (и никаких других параметров, объектов и т. Д.) В своих действиях, заключается в том, что вы попадаете в общую ошибку: применяет только один Interceptor (ваш) вместо , применяя весь перехватчик Stack (который должен содержать ваш):

Вы можете определить его дважды в каждом действии:

<action name="login" class="ph.edu.iacademy.action.LoginAction"> 
    <interceptor-ref name="defaultStack" /> <!-- this is missing --> 
    <interceptor-ref name="containskeyinterceptor" /> 

или, гораздо лучше, определить его раз в пользовательский стек, и всегда использовать стек:

<interceptors> 
    <interceptor-stack name="yourStack">     
     <interceptor-ref name="defaultStack"/> 
     <interceptor-ref name="containskeyinterceptor"/> 
    </interceptor-stack> 
</interceptors> 

<action name="login" class="ph.edu.iacademy.action.LoginAction"> 
    <interceptor-ref name="yourStack" /> 

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

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

<action name="login" class="ph.edu.iacademy.action.LoginAction"> 
+0

Привет Андреа, когда я получу Сессионную карту, и когда я получу реальный объект HttpSession? – silver

+1

Обычно вам нужна только карта. –

+1

Спасибо, это сработало! Я использовал карту сеанса и подход «определить дважды», теперь я буду экспериментировать с ''. Продвинутый и отмеченный принятый ответ. – silver

2

на основе this я не думаю, что перехватчик может сам/должен быть сеанс в курсе.

Вы можете получить доступ к этой собственности как таковой:

final ActionContext context = actionInvocation.getInvocationContext(); 
this.session = context.getSession(); 

Там может быть способ, чтобы получить этот набор автоматически, я не слишком хорошо знакомы с struts2, но это может быть, что sessionaware работает только для определенное подмножество объектов, и этот перехватчик по какой-то причине не является одним из них. (не сканируется, исключается из сканирования, неправильного типа)

+0

Привет, я удалил все ссылки 'SessionAware' в перехватчик и поместил свой код внутри' intercept() '. 'Session' больше не является нулевым, но теперь я испытываю' NullPointerException' в классе [IndexAction] (http://pastebin.com/v4z4eafj) (строка 9 - session is null). – silver

+1

Это ответил на первый вопрос, +1 –

+0

Кстати, почему он должен быть окончательным? – silver