open/save file in smartGWT

余生颓废 提交于 2019-12-01 14:10:29

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);

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!