Monday 8 September 2014

ReadListener

To process a servlet request, Servlet container uses the server thread. To make Application high available, you must ensures that the threads handling the request are not sitting idle. Lets take a scenario, client sending large amounts of data to the server, using Servlet post request. Due to network delays or some other reasons, client may not send the data as fast as server can read. In these situations the thread used to process this request some times sits idle (waiting for input from client).

There is a solution with Asynchronous processing. For more information about Asynchronous processing, follow the below link.


Asynchronous processing using ReadListener
It supports non blocking read mechanism for servlet and filters in asynchronous mode.

Method Description
onAllDataRead() This method notified when all the data from the specific request has been read.
onDataAvailable() A ServletInputStream instance calls these methods on its listener when there is data available to read.
onError(Throwable t) This method notified when an error occurs while processing the request.

<!DOCTYPE html>
<html>
    <head>
        <title>File Upload</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <form method="POST" action="/servlet/FileUpload" enctype="multipart/form-data" >
            <table>
                <tr>
                    File:<input type="file" name="file" id="file" /><br />
                </tr>
                <tr>
                    Destination:<input type="text" name="destination"/><br />
                </tr>
                <tr>
                    <input type="submit" value="Upload" name="upload" id="upload" />
                </tr>
            </table>
        </form>
    </body>
</html>

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.servlet.annotation.*;

@WebServlet(urlPatterns = {"/FileUpload"}, asyncSupported=true)
public class FileUpload extends HttpServlet {
     
   @Override
   public void doPost(HttpServletRequest request, 
                      HttpServletResponse response)
                      throws IOException {
      final AsyncContext acontext = request.startAsync();
      final ServletInputStream input = request.getInputStream();
      
      input.setReadListener(new ReadListener() {
         byte buffer[] = new byte[10000];
         StringBuilder sbuilder = new StringBuilder();
         @Override
         public void onDataAvailable() {
             System.out.println("Data Available");
            try {
               do {
                  int length = input.read(buffer);
                  sbuilder.append(new String(buffer, 0, length));
               } while(input.isReady());
            } catch (IOException ex) {  }
         }
         @Override
         public void onAllDataRead() {
             System.out.println("All Data Read");
            try {
               acontext.getResponse().getWriter()
                                     .write(sbuilder.toString());
            } catch (IOException ex) {  }
            acontext.complete();
         }
         @Override
         public void onError(Throwable t) {  }
      });
      
      System.out.println("Container thread return back");
   }
  
}

Upload a file with some data, and you can observe the messages like below in server console. 'Container thread return back' message seen immediately, since the request processed in Asynchronous mode.

Info:   Container thread return back
Info:   Data Available
Info:   Data Available
Info:   Data Available
Info:   Data Available
Info:   Data Available
Info:   Data Available
Info:   All Data Read




Prevoius                                                 Next                                                 Home

No comments:

Post a Comment