【问题标题】:Struts2 : actionInvocation.invoke() method gives null pointer exceptionStruts2:actionInvocation.invoke() 方法给出空指针异常
【发布时间】:2012-02-25 20:07:09
【问题描述】:

在我的应用程序中,我添加了拦截器来过滤请求。这里每个用户都与一个菜单列表相关联。因此,如果用户尝试访问与他无关的页面,那么我们会将他重定向到未经授权的User.jsp 页面,否则我们将让用户访问该页面。

这是我的拦截器代码...

 @Override
    public  String intercept(ActionInvocation actionInvocation) throws Exception {
        String returnAction = "unauth.user";
        Map<String, String> keyValMap = FCCommonUtils.getALLMenuIdMap();
        ActionContext context = actionInvocation.getInvocationContext();

        HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
        HttpSession session = null;
        if (request != null) {
            session = request.getSession(false);
            String contextPath = request.getContextPath();
            contextPath = contextPath + RequestURIDtls.SEPERATOR;
            String reqURI = request.getRequestURI().substring(contextPath.length(), request.getRequestURI().length());
            String requestedRole = keyValMap.get(reqURI);

            if (requestedRole != null && session != null) {
                UserInfoUIForm userForm = (UserInfoUIForm) session.getAttribute(WebConstants.USER_INFO);
                if (userForm != null) {
                    List<Long> userRoleLst = FCCommonUtils.getmenuids(userForm.getRoleId());

                    if (userRoleLst.contains(new Long(requestedRole))) {
                        //TODO : GUNJAN : NEED TO DO R&D WHY actionInvocation.invoke() CREATES NULL POINTER EXCEPTION
                        //returnAction=actionInvocation.invoke();                        
                        returnAction = "success";
                    } else {
                        returnAction = "unauth.user";
                    }
                } else {
                    returnAction = "unauth.user";
                }
            } else {
                returnAction = "unauth.user";
            }

        } else {
            returnAction = "unauth.user";
        }
        return returnAction;
    }

在上面的代码中,returnAction=actionInvocation.invoke() 给出了空指针异常。

这是我访问页面的 struts.xml 配置..

<action name="viewCorporate" class="com.ndil.web.corporate.MstCorporateAction" method="viewCorporatePage">
            <interceptor-ref name="menuFilterInterceptor" />
            <result name="unauth.user">/jsp/unAuthUser.jsp</result>
            <result name="success">/jsp/mngCorporate.jsp</result>
        </action>         

谁能告诉我为什么 actionInvocation.invoke() 给出空指针异常???

谢谢, Gunjan Shah。

【问题讨论】:

    标签: struts2 nullpointerexception interceptor


    【解决方案1】:

    免费代码审查。

    1) 拦截结果声明为变量,未使用。

    2) 无论如何,所述值应该是一个常数。

    3) 变量命名错误——它不是动作名称,而是结果名称。

    4) 如果你在拦截器中,你已经收到了一个请求——这不可能是空的。如果它 null,则发生了比未经授权的用户更严重的事情,世界应该爆炸。

    5) 同样,除非您已将整个应用专门配置为不创建会话,否则检查会话是多余的。如果你不这样做,那就是出了严重的问题。检查已知会话属性以确定用户是否已登录,而不是检查会话本身是否存在——要容易得多。

    IMO 45,如果需要处理,则应使用声明性异常处理。在这种状态下,Web 应用程序可能无法运行 - 将用户绑定到 HTTP 500 或类似协议。

    6) 嵌套条件方式太深了。严格遵守“每个方法一个返回”会产生难以理解的代码,尤其是当方法具有深度嵌套的条件时。

    7)看起来您是在依赖表单数据来确定用户的角色。这本质上是不安全的;用户角色信息应保存在会话中,不易被篡改。

    8) 一些杂项调整给我们留下了这个:

    public class FooInterceptor {
    
        private static final String UNAUTHORIZED_USER = "unauth.user";
    
        public  String intercept(ActionInvocation actionInvocation) throws Exception {
            ActionContext context = actionInvocation.getInvocationContext();
            HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
            if (request == null) {
                return UNAUTHORIZED_USER;
            }
    
            HttpSession session = request.getSession(false);
            if (session == null) {
                return UNAUTHORIZED_USER;
            }
    
            Long requestedRole = getRequestedRole(request);
            if (requestedRole == null) {
                return UNAUTHORIZED_USER;
            }
    
            UserInfoUIForm userForm = (UserInfoUIForm) session.getAttribute(WebConstants.USER_INFO);
            if (userForm == null) {
                return UNAUTHORIZED_USER;
            }
    
            List<Long> userRoles = FCCommonUtils.getmenuids(userForm.getRoleId());
            return userRoles.contains(requestedRole) ? ActionSupport.SUCCESS : UNAUTHORIZED_USER;
        }
    
        private Long getRequestedRole(HttpServletRequest request) {
            String contextPath = request.getContextPath() + RequestURIDtls.SEPARATOR;
            String reqURI = request.getRequestURI().substring(contextPath.length(), request.getRequestURI().length());
            try {
                return Long.valueOf(FCCommonUtils.getALLMenuIdMap().get(reqURI));
            } catch (NumberFormatException e) {
                return null;
            }
        }
    }
    

    虽然测试该方法仍然相对困难,但更容易理解精确的测试需求。它更容易阅读,因为您不再需要怀疑“如果相反是真的怎么办?”就像在深度嵌套的代码中一样。

    【讨论】:

      【解决方案2】:

      使用这个:

      <action name="viewCorporate" class="com.ndil.web.corporate.MstCorporateAction" method="viewCorporatePage">
              <interceptor-ref name="defaultStack"></interceptor-ref>
              <interceptor-ref name="menuFilterInterceptor" />
              <result name="unauth.user">/jsp/unAuthUser.jsp</result>
              <result name="success">/jsp/mngCorporate.jsp</result>
          </action>    
      

      当您为动作声明明确指定拦截器时,Struts 不会自动添加此默认拦截器。

      【讨论】:

      • thanx tusar ... 添加 defaultStack 后,它现在可以正常工作了。
      • 但这是正确的答案——请为以后的访问者恢复它。我的回答是作为附加信息;你的答案不是被接受的答案是没有意义的——但不要以此为理由删除你的答案。
      • 完成。 @DaveNewton 我有问题,可以看看吗?stackoverflow.com/q/8937158/778687
      猜你喜欢
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2014-07-19
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多