views:

289

answers:

2

Hi All, I have implemented RPCService, RPCServiceAsync & RPCServieImpl. On clicking a button a service in server side will be called and it will fetch data from DB and file is created. Once the file is created, then i need to open that file in client side and need to prompt a dialog box with open/save options. how can i implement this opening a file part. pls suggest a way to implement t.. Reply pls.. thanks in advance....

@Hambend : I still have one more clarification !.. how to call this doGet method in another servlet i.e. in my onmodule load class i am having lot of widgets in seperate layout and one such a widget is BUTTON ? onclicking this button service RPCServiceImpl is called and all manipulations are done and file is created in a serperate function (public int GenerateFile(String name)() ) . how to make that function to call doGet method ? since doGet needs request,response parameters to be passed along with it?? pls suggest me a method to call that method. thanks in advance

A: 

GWT's RPC services are only able to send java objects back to the client. To send a file back to the user you'll need to use a non-GWT java servlet. Here's some code I've used before for serving up jpeg images from a repository.

public class ImageServlet extends HttpServlet {
    private final String repository = "/var/images/";

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        String filename = request.getParameter("file");

        // Security: '..' in the filename will let sneaky users access files
        // not in your repository.
        filename = filename.replace("..", "");

        File file = new File(repository + filename);
        if (!file.exists())
            throw new FileNotFoundException(file.getAbsolutePath());

        response.setHeader("Content-Type", "image/jpeg");
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-disposition", "attachment;filename=\"" + filename + "\"");

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buf = new byte[1024];
        while (true) {
            int length = bis.read(buf);
            if (length == -1)
                break;

            bos.write(buf, 0, length);
        }
        bos.flush();
        bos.close();
        bis.close();
    }
}

"Content-disposition: attachment" should cause most browsers to download the file instead of displaying it, with the filename defaulting to whatever you provide. The way you would use this servlet is to have the user call the RPCService that you already have, which saves the file to the repository folder. Then, you link or redirect them to this servlet with a url such as http://your.domain.com/fileServlet?file=myFile.jpg. Obviously with this setup you have a security risk where users can download other people's files if they can guess the filenames.

What you might like to do is merge the database code from your RPC service into this servlet. There's no need to save the file anywhere on the server, you can take your database results and write them into response.getOutputStream() or response.getWriter() in exactly the same way you would write them to file, except that the result goes straight to the user. As long as you set your content headers correctly the user won't notice the difference.

You can't call this method from another servlet, the only way to make a browser to download it as a file is to access it through a normal HTTP request. First you declare the servlet in your web.xml file like you would a GWT RPC service:

<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>
        com.package.ImageServlet
    </servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/imageServlet</url-pattern>
</servlet-mapping>

Now any HTTP GET requests going to http://your.tomcat.server/webapp/imageServlet will get picked up by ImageServlet.doGet(). Then on the client side you can either make a normal html link to the file:

new HTML("<a href='" + GWT.getHostPageBaseURL() + "imageServlet?file=" + filename + "'>download</a>");

...or, you should be able to put this in a ClickHandler (I haven't tested it):

Window.Location.assign(GWT.getHostPageBaseURL() + "imageServlet?file=" + filename);
hambend
thanks a lot hambend.. still i hav one more clarification ! pls clear it.. how to call this doGet method in another servlet ? in my onmodule load class i am having lot of widgets in seperate layout and one such a widget is BUTTON ? how to trigger that onclick button item to call this method ??
Karthikeyan
I edited my answer to clarify how to use the servlet.
hambend
@Hambend: thanks a lot.... I got it working.... Thanks ..
Karthikeyan
@Hambend: i implemented it with small change.. by implementing a hidden frame and i loaded that servlet from the frame. Thanks a lot for ur help..
Karthikeyan
A: 

If the file is text, then you always back back an Object with an array of Strings.
If binary then simply a byte[] in the class would do.

Romain Hippeau