GWT的RPC服務只能將java對象發送回客戶端。要將文件發送回用戶,您需要使用非GWT Java servlet。以下是我之前用於從存儲庫提供jpeg圖像的代碼。
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();
}
}
「內容處置:附件」應引起大多數瀏覽器下載,而不是顯示它的文件中,文件名默認爲任何你提供。你使用這個servlet的方式是讓用戶調用你已有的RPCService,它將文件保存到存儲庫文件夾中。然後,您將它們鏈接或重定向到此servlet,並使用url,例如http://your.domain.com/fileServlet?file=myFile.jpg。顯然,使用此設置時,如果用戶可以猜測文件名,用戶可以下載其他人的文件,則存在安全風險。
您可能想要做的是將RPC服務中的數據庫代碼合併到此servlet中。不需要將文件保存在服務器上的任何位置,您可以將數據庫結果寫入response.getOutputStream()或response.getWriter(),其方式與將文件寫入文件的方式完全相同,只是結果不同直接給用戶。只要您正確設置了內容標題,用戶就不會注意到其中的差異。
您不能從另一個servlet調用此方法,使瀏覽器將其作爲文件下載的唯一方法是通過正常的HTTP請求訪問它。首先聲明這個servlet中像使用GWT RPC服務web.xml文件:
<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>
現在,任何HTTP GET請求要http://your.tomcat.server/webapp/imageServlet將ImageServlet.doGet得到回升()。然後在客戶端,你可以做一個普通的HTML文件鏈接:
new HTML("<a href='" + GWT.getHostPageBaseURL() + "imageServlet?file=" + filename + "'>download</a>");
...或者,你應該能夠把這個在clickHandler事件(我沒有測試):
Window.Location.assign(GWT.getHostPageBaseURL() + "imageServlet?file=" + filename);
你需要將它保存在客戶端,還是可以將它保存在服務器端?客戶端的問題是讓瀏覽器的沙箱允許你操縱本地文件系統。 – 2010-06-16 14:02:29