【问题标题】:Download files from directory and sub-directory - Using Java, JSP从目录和子目录下载文件 - 使用 Java、JSP
【发布时间】:2018-10-10 17:16:48
【问题描述】:

我正在开发一个示例应用程序来从目录及其子目录下载日志文件。我正在为我的应用程序使用 Spring Boot 和 jsp 技术。

下面提到的 ReviewController 类负责列出指定目录(即 EXTERNAL_FILE_PATH 及其子目录)中的所有文件,并将相同的列表发送到 review.jsp 页面。

@Controller
public class ReviewController {

    private static final String EXTERNAL_FILE_PATH = "C:\\work\\demo-logs\\";


    @RequestMapping("/review")
    public ModelAndView reviewPage() {
        String root=EXTERNAL_FILE_PATH;
        java.io.File file;
        java.io.File dir = new java.io.File(root);
        List<String> list = new ArrayList<String>();
        List<String> fileList =displayDirectoryContents(dir,list);
        ModelAndView model = new ModelAndView("review");
        model.addObject("lists", fileList);
        return model;


    }

    public List<String> displayDirectoryContents(File dir,List<String> list) {

        try {
            File[] files = dir.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    System.out.println("directory:" + file.getName());

                    displayDirectoryContents(file,list);
                } else {
                    System.out.println("     file:" + file.getName());
                    list.add(file.getName());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

}

我的review.jsp代码如下所示。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <h1>Logs Monitoring App</h1>

    </br>
    </br>

    </br>
    <c:if test="${not empty lists}">

        <ul>
            <c:forEach var="listValue" items="${lists}">

                <li><a href='/download/file/<c:out value="${listValue}"  />'>${listValue}</a>
            </c:forEach>
        </ul>

    </c:if>
</body>
</html>

在上面的jsp中,我正在迭代列表并将文件名显示为超链接。

我还有一个控制器负责在用户单击 jsp 中的链接时下载文件。以下是相同的代码

@RestController
@RequestMapping("/download")
public class LogFileDownloadController {

    private static final String EXTERNAL_FILE_PATH = "C:\\work\\demo-logs\\";

    @RequestMapping("/file/{fileName:.+}")
    public void downloadPDFResource(HttpServletRequest request, HttpServletResponse response,
            @PathVariable("fileName") String fileName) throws IOException {

        File file = new File(EXTERNAL_FILE_PATH + fileName);

        if (file.exists()) {


            String mimeType = URLConnection.guessContentTypeFromName(file.getName());
            if (mimeType == null) {

                mimeType = "application/octet-stream";
            }

            response.setContentType(mimeType);




            response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() + "\""));
response.setContentLength((int) file.length());

            InputStream inputStream = new BufferedInputStream(new FileInputStream(file));

            FileCopyUtils.copy(inputStream, response.getOutputStream());

        }
    }

}

我的担忧如下。

  1. 在我的 jsp 中,我可以显示主目录及其子目录下的文件名。但只能从主目录下载文件。 IE。 "C:\work\demo-logs\" 但无法下载文件 存在于嵌套目录下。例如,文件存在于 “C:\work\demo-logs\sub\”。请建议我如何实现它?

  2. 我是否需要使用除 jsp 之外的任何其他技术来轻松 实施。我还需要显示目录名称和 子目录名称,当用户点击它时,它应该展开并 显示它下面的文件。一旦用户点击文件名,它应该会被下载。

【问题讨论】:

  • 大家好,有什么方法可以将 file.getAbsolutePath() 路径参数发送到控制器方法?我尝试使用以下方法 @RequestMapping("/download/{fileName:.+}") public void downloadLogFiles(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName) throws IOException {}。但是这样,当我单击 jsp 文件中的链接时,它并没有到达我的控制器。如果我使用 file.getName() 那么它正在到达。要从嵌套目录下载文件,我使用的是 file.getAbsolutePath()。

标签: java jsp spring-boot jstl


【解决方案1】:

您可以使用 Files.walk 来简化它。它具有参数深度,因此您可以指定子目录的深度级别。

首先创建一个路径对象。

路径 file_path = Paths.get("/home/User/mypath");

然后列出带有子目录的目录

public Stream<Path> loadFiles() {
    try {
        return Files.walk(file_path, 1)
    }
    catch (IOException e) {
        throw new RuntimeException("\"Failed to read stored file");
    }
}

您可以将深度更改为 Files.walk(file_path, 2) 如果你愿意,你可以过滤文件和目录为

Files.walk(file_path, 1).filter(Files::isRegularFile)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2013-06-21
    • 2021-07-02
    • 2011-01-01
    • 2015-07-16
    相关资源
    最近更新 更多