Servlet把classpath中的檔案寫出可供下載的方法如下。
下面的DemoServlet.doGet()
負責寫出檔案。
檔案duke.png
放在Maven專案的src/main/resources/imgs
中,也就是classpath下的imgs
目錄,因此利用ClassLoader.getResourceAsStream(String name)
來取得檔案。
若檔案放在WebContent下則改用ServletContext.getResourceAsStream(String path)
。
輸出前要設定HttpServletResponse
的Content-Type及Content-disposition,分別說明寫出檔案的媒體類型及檔案名稱。
DemoServlet
package com.abc.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DemoServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
if (StringUtils.isEmpty(pathInfo)) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
if ("/download".equalsIgnoreCase(pathInfo)) {
response.setContentType("image/png"); // 寫出檔案的媒體類型為png
response.setHeader("Content-disposition", "attachment; filename=image.png"); // 以附件的方式將檔案寫出,檔案名稱為image.png
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream is = classLoader.getResourceAsStream("imgs/duke.png");
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
while ((is.read(buffer)) != -1) {
os.write(buffer);
}
os.flush();
os.close();
is.close();
return;
}
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
寫出檔案也可用Apache Commons IO的IOUtils.toByteArray(InputStream input)
把輸入串流轉成byte[]
再交給OutputStream
寫出。
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream is = classLoader.getResourceAsStream("imgs/duke.png");
OutputStream os = response.getOutputStream();
byte[] bytes = IOUtils.toByteArray(is);
os.write(bytes);
os.flush();
os.close();
is.close();
範例專案的context path為servlet-demo
,DemoServlet
的servlet path為/demo/*
。所以在瀏覽器url欄位輸入http://localhost:8080/servlet-demo/demo/download
即可進入DemoServlet.doGet()
並下載檔案。
下載檔案請求的Response Header如下。
專案目錄結構。
參考github。
沒有留言:
張貼留言