0

I'm developing a struts2 (2.1.8) web app. I want to use execAndWait interceptor in order to show a wait page while the uploaded file is processed.

After soving the thread problem (execAndWait Interceptor not redirecting to success page after waiting), I haven't a NPE accessing to getText() method I continue having some problems.

If debug the action execution all the jsp form variables (including the file that is uploaded) are ok (with debug inspector I could see the file path, the contentType, the filename), but the file is not in the directori it has to be:

C:\apps\apache-tomcat-6.0.39\work\Catalina\localhost\validador\upload_24cd6d23_a0ec_4887_a47c_7af1f5b703d1_00000002.tmp

I've also read this post: Cannot find file source when processing file with execAndWait interceptor of struts-jquery

But I've already declared a custom interceptor stack including the default-stack:

<interceptors>          
  <interceptor name="execAndWaitExtended" class="aoc.interceptor.myExecuteAndWaitInterceptor"></interceptor>
    <interceptor-stack name="waitStack">
      <interceptor-ref name="defaultStack" />               
      <interceptor-ref name="execAndWaitExtended" />                
    </interceptor-stack>
</interceptors>

my Action declaration:

<package name="default" namespace="/" extends="struts-default" >
...
    <action name="uploadUpdatePDF" class="aoc.action.signature.UpdatePDFUpload">
        <interceptor-ref name="waitStack"/>         
        <result type="tiles" name="input">tilesDef.validacioUpdatePDF</result>          
        <result name="wait">pages/wait.jsp</result>
        <result type="tiles" name="sucess">tilesDef.validacioUpdatePDFResult</result>
    </action>

Understanding the Thread issue is solved, and the filename or filepath from the uploaded file seems ok debuging, I don't understand why the file isn't actually stored in the server directory (and it worked fine before execAndWait interceptor was added).

Any suggestion?

Community
  • 1
  • 1
exoddus
  • 2,230
  • 17
  • 27

1 Answers1

0

I'm not sure what your myExecuteAndWaitInterceptor does, but it needs to make a copy of the file so that it's available to the background thread that runs your action.

In the code below I'm assuming there's a base class called AbstractUploadAction that implements the the methods you need to upload a file (i.e. getting the file and the file name).

public class CustomExecuteAndWaitInterceptor extends org.apache.struts2.interceptor.ExecuteAndWaitInterceptor {

  @Override
  protected BackgroundProcess getNewBackgroundProcess(String name, ActionInvocation actionInvocation,
      int threadPriority) {

    BackgroundProcess bgProcess;
    if (actionInvocation.getAction() instanceof AbstractUploadAction) {
      AbstractUploadAction uploadAction = (AbstractUploadAction)actionInvocation.getAction();
      try {
        File origFile = uploadAction.getUpload();
        if (origFile != null) {
          File altFile = new File(origFile.getParentFile(), origFile.getName() + "-alt.tmp");
          FileUtils.copyFile(origFile, altFile);
          altFile.deleteOnExit();
          uploadAction.setUpload(altFile);
        }
      } catch (Exception ex) {
        throw new RuntimeException("Error copying uploaded file", ex);
      }
      bgProcess = new UploadBackgroundProcess(name + "BackgroundThread", actionInvocation, threadPriority);
    } else {
      bgProcess = super.getNewBackgroundProcess(name, actionInvocation, threadPriority);
    }
    return bgProcess;
  }


  /**
   * Wraps the standard {@link BackgroundProcess} to clean up alternate file created above.
   */
  private class UploadBackgroundProcess extends BackgroundProcess {

    public UploadBackgroundProcess(String threadName, ActionInvocation invocation, int threadPriority) {
      super(threadName, invocation, threadPriority);
    }

    @Override
    protected void afterInvocation() throws Exception {
      super.afterInvocation();
      FileUtils.deleteQuietly(((AbstractUploadAction)getAction()).getUpload());
    }
  }
}

When using the execute and wait interceptor you should generally assume that any resource you might want that is not directly available to your action will not be available to you unless you make a copy of it or have it injected before the execAndWait interceptor starts.

Mark Woon
  • 2,046
  • 1
  • 20
  • 26
  • Thanks for your response Mark! Unfortunately too late, I switched over another solution (change the web flow). – exoddus May 08 '14 at 08:40