2

I have created a custom interceptor MyInterceptor.java in Struts 2, which take the parameters value username and password from index.jsp page and convert the String in these parameters to uppercase.

Below is my interceptor code in which I am getting java.lang.NullPointerException on Line no. 14

MyInterceptor.java:

package com.interceptor;

import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.ActionInvocation;

public class MyInterceptor implements Interceptor{
    public void init(){}
    @Override
    public String intercept(ActionInvocation ai) throws Exception {
        ValueStack stack = ai.getStack();
        String s1 = stack.findString("name");
        String s2 = stack.findString("password");
    String s3 = s1.toUpperCase();
     String s4 = s2.toUpperCase();
        stack.set("name", s3);
        
        stack.set("password", s4);
        return ai.invoke();
    }
    
    @Override
    public void destroy() {
        
    }
}

Here is my index.jsp page:

which takes username and password "ravi":

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login Page</title>
</head>
<body>
<h1>Login Here</h1>
<s:form action="login">

    <s:textfield name="name" label="Name"></s:textfield>
    <s:textfield type="password" name="password" label="Password"></s:textfield>
<s:submit label="Login"></s:submit>
</s:form>
</body>
</html>

Here is action class MyAction.java:

package com.ravi.action;
import com.opensymphony.xwork2.ActionSupport;
public class MyAction extends ActionSupport{
           public String name;
           public String password;

           public void setName(String name){
                                              this.name= name;
                        }

           public void setPassword(String password){
                                                    this.password= password;
                       }

          public String getName(){
                                    return name;
                       }

         public String getPassword(){
                                    return password;
                       }

         public String execute()throws Exception{
                    if(name.equals("RAVI") && password.equals("RAVI")){
                                                       
                                                          return "success";
                                   }
                                   else {
                                                          return "error";

                                    }

                      }


}

And here is my struts.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
    <package name="default" namespace="/" extends="struts-default">

        <interceptors >
            <interceptor name="uppername" class="com.interceptor.MyInterceptor"></interceptor>
        </interceptors>

        <action name="login" class="com.ravi.action.MyAction">
                <interceptor-ref name="uppername"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>  

                <result name="success" >welcome.jsp</result>
                <result name="error">Error.jsp</result>
        </action>

</package>
</struts>

And the Stacktrace is as follows:

java.lang.NullPointerException 
    com.interceptor.MyInterceptor.intercept(MyInterceptor.java:14)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:567)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2522)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2511)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:1)
    java.lang.Thread.run(Unknown Source)

I guess the problem lies in accessing the request parameters in the MyInterceptor.java. The ValueStack's method findString() is not returning the values of parameters name and password.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Ravi Rajput
  • 539
  • 4
  • 12

2 Answers2

2

If you need parameters in the interceptor you should get it from the action context.

Map<String, Object> params = ActionContext.getContext().getParameters();

You were trying to get properties (not parameters) from the value stack while browsing index.jsp, and value stack doesn't have such keys.

String[] s1 = (String[]) params.get("name");
String[] s2 = (String[]) params.get("password");
if (s1 != null && s2 != null) { 
  s1[0] = s1[0].toUpperCase();
  s2[0] = s2[0].toUpperCase();
}
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • 1
    Thanks Roman sir I was waiting for your comment. I am making these changes right now! – Ravi Rajput Apr 09 '16 at 13:15
  • Sir, It didn't Worked!! a small change was needed in struts.xml that I have added in my answer. There is again one problem I am facing, I request you to please go through the answer below. Thanks – Ravi Rajput Apr 09 '16 at 13:43
  • The change is not needed, but if you want to set a property of the action you may try `setValue()` or `setParameter()`. – Roman C Apr 09 '16 at 13:53
  • 1
    sir, Thank you so much, I accessed the parameters from the action context as per your answer and I didnt changed my `struts.xml`. Now everything is working as expected! – Ravi Rajput Apr 10 '16 at 07:48
1

I think the problem should be because of the order of the interceptors. Your interceptor is the last interceptor, so when an action is requested,

  1. Struts make a new instance of your action
  2. The parameter interceptor (which is in default stack) populate the action properties.
  3. After that your interceptor will update the value stack, which of-course, no one will use it.
Alireza Fattahi
  • 42,517
  • 14
  • 123
  • 173
  • Well, I mean logically, the `uppername` should be before `defaultstack`, if you face `Nullpointer exception` you should solve it other way, for example as mentioned in http://stackoverflow.com/questions/30076242/changing-request-parameter-value-in-struts2-interceptor you may define new values and put them in stack and use does new varabiles. For example create `uppercaseName` and `uppercasePassword` in value stack and your action should use them. – Alireza Fattahi Apr 10 '16 at 03:58
  • Also if you want to do it in general and do it with interceptor, you may extend struts `ParametersInterceptor` and override `setParameters()` method (around line 300). – Alireza Fattahi Apr 10 '16 at 04:03