简体   繁体   中英

Struts2: How can I monitor the progress of an SERVER SIDE Action streaming?

I have a Struts 2 Action, and Struts 2 is at SERVER SIDE, to allow user to download files from my application.

The files are stored inside a database (I know... but keep the focus). The user access the action, I get the file from database and send to user by using a Stream.

@Action(value="getFile", results= {  
        @Result(name="ok", type="stream", params = {
                "contentType", "application/octet-stream",
                "inputName", "fileInputStream",
                "contentDisposition", "filename=\"${fileName}\"",
                "bufferSize", "1024"
        }) }
)  

...

public class GetFileAction {
    private String fileName;
    private Integer idFile;
    private ByteArrayInputStream fileInputStream;

    public String execute () {
            ...
            try {
                FileService fs = new FileService();
                if ( (idFile != null) && ( idFile > -1 ) ) {
                    file = fs.getFile( idFile );
                }

                if ( file != null ) {
                    byte[] theFile = file.getFile();

                    fileInputStream = new ByteArrayInputStream( theFile );
                    fileName = file.getFileName();
                } else {
                    //
                }

            } catch ( Exception e ) {
                //
            }
...

All is working as I wish, but I want to monitor ( from my Tomcat container - SERVER SIDE, not the user's browser ) from server side the progress of user download ...

Is it possible?

Thanks.

If you want to monitor the user download on your server then you need to define your own stream result type. As the struts stream result class doesn't log or generate these data.

You can extend the StreamResult . Please have a look at doExecute method. You can see

 while (-1 != (iSize = inputStream.read(oBuff))) {
                oOutput.write(oBuff, 0, iSize);
  }

Here you can find how much data is read from your file. You may put some logs here. The while loops repeats for every buffer size ( which is 2048 by default). A simple counter in this loop will show you how much data you have read

 int totalBlock = 0 ;
 while (-1 != (iSize = inputStream.read(oBuff))) {
           oOutput.write(oBuff, 0, iSize);
           totalBlock ++;
          log.debug( totalBlock * 2048  + "  is read so far");
      }

Ok guys. I found the trick here:

http://www.java2s.com/Code/Android/File/InputStreamthatnotifieslistenersofitsprogress.htm

Just implemented my own listener:

public class ProgressListener implements OnProgressListener {

    @Override
    public void onProgress(int percentage, Object tag) {
        System.out.println( (String)tag + " " + percentage + "%" );

    }

}

And changed my Struts 2 Action to:

@Action(value="getFile", results= {  
        @Result(name="ok", type="stream", params = {
                "contentType", "application/octet-stream",
                "inputName", "fileInputStream",
                "contentDisposition", "filename=\"${fileName}\"",
                "bufferSize", "1024"
        }) }
)   

@ParentPackage("default")
public class GetFileAction extends BasicActionClass {
    private String fileName;
    private Integer idFile;
    private ProgressAwareInputStream fileInputStream;

    public String execute () {
        cmabreu.sagitarii.persistence.entity.File file = null;

        try {
            FileService fs = new FileService();
            if ( (idFile != null) && ( idFile > -1 ) ) {
                file = fs.getFile( idFile );
            }

            if ( file != null ) {
                fileName = file.getFileName();
                byte[] theFile = file.getFile();

                ProgressAwareInputStream pais = new ProgressAwareInputStream( new ByteArrayInputStream( theFile ), 
                        theFile.length, fileName );

                pais.setOnProgressListener( new ProgressListener() );

                fileInputStream = pais; 

            } else {
                //
            }

        } catch ( Exception e ) {
            //
        }

        return "ok";
    }

    ... getters and setters .

}

And the result when I go to http://myapplication:8080/getFile?idFile=1234 was printed on Tomcat console (for now):

6FB377291.g6.txt.dot.gif 21%
6FB377291.g6.txt.dot.gif 42%
6FB377291.g6.txt.dot.gif 63%
6FB377291.g6.txt.dot.gif 84%
6FB377291.g6.txt.dot.gif 100%

Sounds perfect to me!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM