0

In my application I have added interceptor to filter the request.Here each user is associated with a list of menu. So if user try to access page which is not associated to him then we will redirect him to unauthorizedUser.jsp page otherwise we will let the user to access the page.

Here is my interceptor code ...

 @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;
    }

In above code returnAction=actionInvocation.invoke() gives null pointer exception.

Here is my struts.xml configuration to access the page ..

<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>         

Can any one suggest me why actionInvocation.invoke() gives null pointer exception ???

Thanks, Gunjan Shah.

Gunjan Shah
  • 5,088
  • 16
  • 53
  • 72

2 Answers2

4

Free code review.

1) Intercept result decared as variable, unused.

2) Said value should be a constant anyway.

3) Variable is named incorrectly--it's not an action name, it's a result name.

4) If you're in an interceptor, you've gotten a request--there's just no way for this to be null. If it is null, something far more serious than an unauthorized user has occurred, and the world should blow up.

5) Similarly, unless you've specifically configured your entire app not to create sessions, checking for a session is redundant. If you don't, something has gone horribly wrong. Check for known session attributes to determine if a user is logged in, not for the presence of the session itself--much easier.

IMO both 4 and 5, if handled at all, should be handled with declarative exceptions. In that state, the web app is likely inoperable--peg the user to HTTP 500 or similar.

6) The nested conditionals are way too deep. Strict adherence to "one return per method" creates difficult-to-understand code, particularly when a method has deeply-nested conditionals.

7) It looks like you're relying on form data to determine the user's role. This is inherently insecure; user role information should be kept in the session, where it can't be easily manipulated.

8) Some miscellaneous tweaks leave us with this:

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;
        }
    }
}

While testing the method remains relatively difficult, it's much easier to understand the precise testing needs. It's easier to read, because you no longer have to wonder "what if the opposite is true?" as in the deeply-nested code.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
1

Use this:

<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 won't add this default interceptor automatically when you are explicitly specifying a interceptor for action declaration.

tusar
  • 3,364
  • 6
  • 37
  • 60
  • thanx tusar ... Its workin fine now after adding the defaultStack. – Gunjan Shah Feb 06 '12 at 12:51
  • 1
    But it's the correct answer--please revert it back for future visitors. My answer was meant as additional information; it makes no sense that yours wasn't the accepted answer--but don't use that as a reason to remove yours. – Dave Newton Mar 24 '12 at 18:58
  • Done. @DaveNewton I had a problem, could please have a look at it ?http://stackoverflow.com/q/8937158/778687 – tusar Apr 03 '12 at 05:25