網頁

2020/9/6

Servlet 下載classpath的檔案 download file in classpath

Servlet把classpath中的檔案寫出可供下載的方法如下。

下面的DemoServlet.doGet()負責寫出檔案。

檔案duke.png放在Maven專案的src/main/resources/imgs中,也就是classpath下的imgs目錄,因此利用ClassLoader.getResourceAsStream(String name)來取得檔案。

若檔案放在WebContent下則改用ServletContext.getResourceAsStream(String path)

輸出前要設定HttpServletResponseContent-TypeContent-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-demoDemoServlet的servlet path為/demo/*。所以在瀏覽器url欄位輸入http://localhost:8080/servlet-demo/demo/download即可進入DemoServlet.doGet()並下載檔案。

下載檔案請求的Response Header如下。



專案目錄結構。



參考github


沒有留言:

張貼留言