我看到了一些建议,比如将图像目录作为指向Web容器外部目录的符号链接,但是这种方法在Windows和*nix环境中都能工作吗?
如果您遵守*nix文件系统路径规则(即使用独占斜杠,如/path/to/files),那么它也可以在Windows上工作,而不需要摆弄丑陋的东西File.separator串连接。但是,它只能在调用此命令的同一工作磁盘上扫描。因此,例如,如果Tomcat安装在C:然后/path/to/files实际上会指向C:\path\to\files.
如果文件都位于webapp之外,并且您希望Tomcat的DefaultServlet要处理这些问题,您在Tomcat中所需要做的就是将以下上下文元素添加到/conf/server.xml内标签:
这样他们就可以通过http://example.com/files/.....Glassfish/Payara配置示例可以找到这里和WildFly配置示例可以找到这里.
如果您想自己控制读写文件,那么您需要创建一个Servlet对于这个基本上只得到一个InputStream文件的样式,例如FileInputStream并将其写入OutputStream.的.HttpServletResponse.
在响应中,您应该设置Content-Type标头,以便客户端知道要将哪个应用程序与所提供的文件关联。而且,您应该设置Content-Length标头,以便客户端可以计算下载进度,否则它将是未知的。而且,您应该设置Content-Disposition头到attachment如果你想存为对话框,否则客户端将尝试将其内联显示。最后,只需将文件内容写入响应输出流即可。
下面是这样一个servlet的基本示例:@WebServlet("/files/*")public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String filename = URLDecoder.decode(request.getPathInfo().substring(1), "UTF-8");
File file = new File("/path/to/files", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(filename));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
Files.copy(file.toPath(), response.getOutputStream());
}}
映射到url-pattern例如/files/*,然后你就可以通过http://example.com/files/image.png..这样,您可以更多地控制请求,而不是DefaultServlet,例如提供默认图像(即if (!file.exists()) file = new File("/path/to/files", "404.gif"))。也使用request.getPathInfo()以上为首选request.getParameter()因为它对SEO更友好,否则IE将不会选择正确的文件名。存为.
您可以重用相同的逻辑来从数据库服务文件。简单地替换new FileInputStream()通过ResultSet#getInputStream().
希望这能帮上忙。
另见: