Search code examples
javagwtservletssmartgwt

Get call back from Servlet in GWT when Upload file in SmartGWT's dynamic form without using DataSource


I am using SmartGWT Dynamic form submitForm() to implement a file upload functionality in the client side, here is the code:

final String DEFAULT_FILE_UPLOAD_SERVICE_PATH = "upload";
final String TARGET = "uploadTarget";

VLayout body = new VLayout();

uploadForm = new DynamicForm();

 // initialise the hidden frame
NamedFrame frame = new NamedFrame(TARGET);
frame.setWidth("1px");
frame.setHeight("1px");
frame.setVisible(false);

uploadForm.setEncoding(Encoding.MULTIPART);
uploadForm.setMethod(FormMethod.POST);
// set the (hidden) form target
uploadForm.setTarget(TARGET);

uploadForm.setAction(DEFAULT_FILE_UPLOAD_SERVICE_PATH);

// initialise the File name field
uploadItem = new UploadItem("filename");
uploadItem.setName("filename");
uploadItem.setTitle("File name");

// set the fields into the form
uploadForm.setFields(uploadItem);

// add the Upload Form and the (hidden) Frame to the main layout container
body.addMember(uploadForm);
body.addMember(frame);

And in the server side I have a servlet to handle the file upload request using Apache File Upload library, here is the code:

@Singleton
@SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.process(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.process(request, response);
    }

    private void process(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // check that we have a file upload request
        if (ServletFileUpload.isMultipartContent(request)) {
            processFiles(request, response);
        }
    }

    private File tmpDir;
    private static final String DESTINATION_DIR_PATH = "/files/upload";
    private File destinationDir;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        tmpDir = new File(((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).toString());

        if (!tmpDir.isDirectory()) {
          throw new ServletException(tmpDir.toString() + " is not a directory");
        }

        Log.debug("tmpDir: " + tmpDir.toString());

        String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
        destinationDir = new File(realPath);

        if (!destinationDir.isDirectory()) {
          throw new ServletException(DESTINATION_DIR_PATH + " is not a directory");
        }
    }

    private void processFiles(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {

        // create a factory for disk-based file items
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // set the size threshold, above which content will be stored on disk
        factory.setSizeThreshold(1 * 1024 * 1024); // 1 MB

        // set the temporary directory (this is where files that exceed the threshold will be stored)
        factory.setRepository(tmpDir);

        // create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);

        try {
            // parse the request
            List<?> items = upload.parseRequest(request);

            // process the uploaded items
            Iterator<?> itr = items.iterator();

            while (itr.hasNext()) {
                FileItem item = (FileItem) itr.next();

                // write the uploaded file to the application's file staging area
                File file = new File(destinationDir, item.getName());
                item.write(file);
            }

        } catch (FileUploadException e) {
            Log.error("Error encountered while parsing the request", e);
        } catch (Exception e) {
            Log.error("Error encountered while uploading file", e);
        }
    }
}

With the above code, files upload works fine. My question is I don't know how to get the call back from servlet. One tutorial says about using the hidden frame, but I don't know how to do that. Could anyone help me with this? Thanks.


Solution

  • You need to write out a tag as your server response, containing JavaScript code which will execute inside the frame. This code will need to navigate out of the frame to call some function you have put into the main page (eg top.someFunction()). To set up the function in the main page, use JSNI to attach a JavaScript function to the window ($wnd in JSNI).

    Note you don't have to do any of this if you're using SmartGWT Pro+ - this solution is just for people using the LGPL version.