Gaurav Gupta
Gaurav Gupta

Reputation: 4691

File upload interceptor does not call setter methods

I need to do very basic file upload operation, but in my case setter methods are not called by file upload interceptor.

I have checked the solution of similar questions like this on stackoverflow but they didnot resolve my issue.

Please let me know what mistake i am doing in code.

Action class

public class ResultFileUploadAction extends ActionSupport {
    private File upload;
    private String uploadFileName;
    private String uploadContentType;
    private Logger logger = Logger.getRootLogger();

    @Override
    public String execute() throws Exception {
        logger.info("ResultFileUploadAction->execute");
        String destPath = "C:/work/";
        try {
            System.out.println("Src File name: " + upload);
            System.out.println("Dst File name: " + uploadFileName);
            File destFile = new File(destPath, uploadFileName);
            FileUtils.copyFile(upload, destFile);

        } catch (IOException e) {
            e.printStackTrace();
            return ERROR;
        }

        return super.execute();
    }

    public void setUpload(File upload) {
        this.upload = upload;
    }

    public void setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }
}

Jsp file

<body>

    <s:form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="upload" id="uploadfile" />
        <input type="submit" id="submit" />
    </s:form>
</body>

Struts.xml

<interceptors>
    <interceptor name="fileupload"
        class="org.apache.struts2.interceptor.FileUploadInterceptor"></interceptor>
    <interceptor name="servletConfig"
        class="org.apache.struts2.interceptor.ServletConfigInterceptor" />
    <interceptor name="authenticationinterceptor"
        class="interceptors.common.AuthenticationInterceptor"></interceptor>
    <interceptor-stack name="securestack">
        <interceptor-ref name="authenticationinterceptor"></interceptor-ref>
        <interceptor-ref name="servletConfig"></interceptor-ref>

    </interceptor-stack>
</interceptors>

<action name="upload" class="actions.result.ResultFileUploadAction"
    method="execute">
    <interceptor-ref name="securestack"></interceptor-ref>
    <interceptor-ref name="fileupload"></interceptor-ref>
    <result name="success" type="dispatcher">/AddResultBullk.jsp</result>
</action>

Since, setters are not called therefore i am getting NPE in execute().

Upvotes: 0

Views: 1200

Answers (2)

mohamed sulibi
mohamed sulibi

Reputation: 526

When you want to implements a new interceptors, it is a good idea to add them to the default stack in front or back of the chain, i faced the same problem before when I am trying to add an interceptor for authentication and ended with the following practice, I will update your code to mention my idea:

...
<interceptors>    
    <interceptor name="authenticationinterceptor" class="your.class.name" />
    <interceptor-stack name="securestack">
        <interceptor-ref name="authenticationinterceptor" />
        <interceptor-ref name="defaultStack" />
    </interceptor-stack>
</interceptors>
<!--
Implicitly use securestack for all actions.
-->
<default-interceptor-ref name="securestack" />
....
<!-- 
and if you want some actions to pass from secureStack and use defaultStack
(ex login page), you can state that explicitly, See:
-->
<action name="GetLoginPageAction" class="your.class.name">
    <interceptor-ref name="defaultStack" />
    ...
</action>

<!-- 
for upload action you can use interceptor without define 
it in the interceptors tag only in the action, 
Note that you should explicitly use securestack below
-->
<action name="upload" class="actions.result.ResultFileUploadAction">
    <!-- You can remove the below refs because fileUpload is already 
         included in defaultStack that is included in the securestack 
         and securestack is default interceptor for all actions.
    <interceptor-ref name="securestack"/> 
    <interceptor-ref name="fileUpload"/>
    -->
    ...
</action>

I hope these notes help you.

Upvotes: 1

Dave Newton
Dave Newton

Reputation: 160211

As stated in the fileUpload interceptor docs:

It adds the following parameters, where [File Name] is the name given to the file uploaded by the HTML form. [fileName, contentType]

When mucking with interceptor stacks there are always two plans of attack:

  • Try a non-custom stack
  • Don't mess with the stack unless you know precisely why you're doing it, and what you're doing.

Also, actions that are configured to use almost no interceptors, as yours is, are almost always suspect, because they eliminate the bulk of framework functionality. Params in particular is key to essentially every form-based action.

Upvotes: 1

Related Questions