Struts2:actionInvocation.invoke()方法给出空指针异常

时间:2012-02-03 06:43:00

标签: struts2 nullpointerexception interceptor

在我的应用程序中,我添加了拦截器来过滤请求。每个用户都与一个菜单列表相关联。因此,如果用户尝试访问与他无关的页面,那么我们会将他重定向到unauthorizedUser.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。

2 个答案:

答案 0 :(得分:4)

免费代码审核。

1)拦截结果被视为变量,未使用。

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

3)变量名称不正确 - 它不是动作名称,而是结果名称。

4)如果你在一个拦截器中,你已经得到了一个请求 - 那就没有办法让它成为空。如果 为null,则会发生比未经授权的用户更严重的事情,并且世界应该爆炸。

5)同样,除非您专门配置整个应用程序不创建会话,否则检查会话是多余的。如果你不这样做,有些事情已经发生了可怕的错误。检查已知的会话属性以确定用户是否已登录,而不是存在会话本身 - 更容易。

IMO 4 5 ,如果完全处理,则应使用声明性异常处理。在该状态下,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;
        }
    }
}

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

答案 1 :(得分:1)

使用此:

<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不会自动添加此默认拦截器。