在Java Web应用程序中从应用程序服务器外部提供静态数据的最简单方法 [英] Simplest way to serve static data from outside the application server in a Java web application

查看:159
本文介绍了在Java Web应用程序中从应用程序服务器外部提供静态数据的最简单方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在Tomcat上运行的Java Web应用程序。我想加载静态图像,这些图像将在Web UI和应用程序生成的PDF文件中显示。此外,还将通过Web UI上传添加和保存新图像。

I have a Java web application running on Tomcat. I want to load static images that will be shown both on the Web UI and in PDF files generated by the application. Also new images will be added and saved by uploading via the Web UI.

通过将静态数据存储在Web容器中但存储来执行此操作不是问题从Web容器外部加载它们让我很头疼。

It's not a problem to do this by having the static data stored within the the web container but storing and loading them from outside the web container is giving me headache.

我不想在此时使用像Apache这样的单独Web服务器来提供静态数据。我也不喜欢在二进制数据库中存储图像的想法。

I'd prefer not to use a separate web server like Apache for serving the static data at this point. I also don't like the idea of storing the images in binary in a database.

我见过一些建议,比如将图像目录作为指向Web容器外部目录的符号链接,但这种方法在Windows和* nix上都能正常工作环境?

I've seen some suggestions like having the image directory being a symbolic link pointing to a directory outside the web container, but will this approach work both on Windows and *nix environments?

有人建议编写一个过滤器或servlet来处理图像服务,但这些建议非常模糊和高级别,没有指向如何实现这一点的更详细信息。

Some suggest writing a filter or a servlet for handling the image serving but those suggestions have been very vague and high-level without pointers to more detailed information on how to accomplish this.

推荐答案


我看过一些建议,比如将图像目录作为符号链接指向Web容器外的目录,但这种方法是否适用于Windows和* nix环境?

如果你遵守* nix文件系统路径规则(即你在 / path / to / files 中使用专有的正斜杠),那么它也适用于Windows而不需要用丑陋的 File.separator 字符串连接来解决问题。但是,它只能在与调用此命令的位置相同的工作磁盘上进行扫描。因此,如果Tomcat例如安装在 C:上,那么 / path / to / files 实际上会指向 C:\ path\to\files

If you adhere the *nix filesystem path rules (i.e. you use exclusively forward slashes as in /path/to/files), then it will work on Windows as well without the need to fiddle around with ugly File.separator string-concatenations. It would however only be scanned on the same working disk as from where this command is been invoked. So if Tomcat is for example installed on C: then the /path/to/files would actually point to C:\path\to\files.

如果这些文件都位于webapp之外,那么你想要使用Tomcat的 DefaultServlet 来处理它们,那么你在Tomcat中基本上需要做的就是将以下Context元素添加到 / conf / server。 xml < Host> 标签内:

If the files are all located outside the webapp, and you want to have Tomcat's DefaultServlet to handle them, then all you basically need to do in Tomcat is to add the following Context element to /conf/server.xml inside <Host> tag:

<Context docBase="/path/to/files" path="/files" />

这样他们就可以通过 http://example.com访问/文件/...。 GlassFish / Payara配置示例可以在此处找到,可以在此处找到WildFly配置示例/ a>。

This way they'll be accessible through http://example.com/files/.... GlassFish/Payara configuration example can be found here and WildFly configuration example can be found here.

如果你想自己控制读/写文件,那么你需要创建一个 Servlet 为此,它基本上只获得了一个 InputStream 的文件,例如 FileInputStream ,并将其写入 HttpServletResponse 的OutputStream

If you want to have control over reading/writing files yourself, then you need to create a Servlet for this which basically just gets an InputStream of the file in flavor of for example FileInputStream and writes it to the OutputStream of the HttpServletResponse.

在回复中,您应该设置 Content-Type 标头,以便客户端知道与提供的文件关联的应用程序。并且,您应该设置 Content-Length 标头,以便客户端可以计算下载进度,否则将是未知的。并且,如果您想要另存为 Content-Disposition 标头设置为附件 >对话框,否则客户端将尝试内联显示它。最后只需将文件内容写入响应输出流。

On the response, you should set the Content-Type header so that the client knows which application to associate with the provided file. And, you should set the Content-Length header so that the client can calculate the download progress, otherwise it will be unknown. And, you should set the Content-Disposition header to attachment if you want a Save As dialog, otherwise the client will attempt to display it inline. Finally just write the file content to the response output stream.

以下是此类servlet的基本示例:

Here's a basic example of such a 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());
    }

}

映射到<$ c时$ c> 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不会选择正确的文件名。

When mapped on an url-pattern of for example /files/*, then you can call it by http://example.com/files/image.png. This way you can have more control over the requests than the DefaultServlet does, such as providing a default image (i.e. if (!file.exists()) file = new File("/path/to/files", "404.gif") or so). Also using the request.getPathInfo() is preferred above request.getParameter() because it is more SEO friendly and otherwise IE won't pick the correct filename during Save As.

您可以重复使用相同的逻辑来从数据库中提供文件。只需通过 ResultSet#getInputStream()替换 new FileInputStream()

You can reuse the same logic for serving files from database. Simply replace new FileInputStream() by ResultSet#getInputStream().

希望这会有所帮助。

  • Recommended way to save uploaded files in a servlet application
  • Abstract template for a static resource servlet (supporting HTTP cache)
  • How to retrieve and display images from a database in a JSP page?
  • How to stream audio/video files such as MP3, MP4, AVI, etc using a Servlet

这篇关于在Java Web应用程序中从应用程序服务器外部提供静态数据的最简单方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆