我有一个在 Tomcat 上运行的 Java Web 应用程序。我想加载将在 Web UI 和应用程序生成的 PDF 文件中显示的静态图像。此外,新图像将通过 Web UI 上传来添加和保存。
通过将静态数据存储在 Web 容器中来做到这一点不是问题,但从 Web 容器外部存储和加载它们却让我头疼。
此时我不想使用像 Apache 这样的单独的 Web 服务器来提供静态数据。我也不喜欢将图像以二进制形式存储在数据库中的想法。
我见过一些建议,例如将图像目录作为指向 Web 容器外部目录的符号链接,但是这种方法在 Windows 和 *nix 环境中都适用吗?
有些人建议编写一个过滤器或 servlet 来处理图像服务,但这些建议非常模糊且高级,没有指向如何完成此操作的更详细信息。
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.
It's not a problem to do this by having the static data stored within the web container but storing and loading them from outside the web container is giving me headache.
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.
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?
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.
发布评论
评论(11)
文件系统路径规则(即您只使用正斜杠,如
/path/to/files
中),那么它也可以在 Windows 上工作,而无需摆弄丑陋的File.separator< /code> 字符串连接。然而,它只会在调用该命令的同一工作磁盘上进行扫描。因此,如果 Tomcat 安装在
C:
上,那么/path/to/files
实际上会指向C:\path\to\files
>。如果这些文件都位于 web 应用程序之外,并且您希望 Tomcat 的
DefaultServlet
来处理它们,那么您在 Tomcat 中基本上需要做的就是将以下 Context 元素添加到/conf /server.xml
位于
标记内:这样就可以通过
http://example.com/files/...
访问它们。对于基于 Tomcat 的服务器(例如 JBoss EAP 6.x 或更早版本),方法基本相同,另请参阅 在这里。 GlassFish/Payara 配置示例可以在此处找到WildFly 配置示例可以在此处< /a>.如果您想自己控制读/写文件,那么您需要为此创建一个
Servlet
,它基本上只是获取文件的InputStream
,例如FileInputStream
并将其写入HttpServletResponse
的OutputStream
。在响应中,您应该设置
Content-Type
标头,以便客户端知道哪个应用程序与提供的文件关联。并且,您应该设置Content-Length
标头,以便客户端可以计算下载进度,否则将未知。而且,如果您想要“另存为”对话框,则应将Content-Disposition
标头设置为attachment
,否则客户端将尝试内联显示它。最后只需将文件内容写入响应输出流即可。下面是此类 servlet 的一个基本示例:
当映射到
/files/*
等url-pattern
时,您可以通过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()
即可。另请参阅:
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 uglyFile.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 onC:
then the/path/to/files
would actually point toC:\path\to\files
.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:This way they'll be accessible through
http://example.com/files/...
. For Tomcat-based servers such as JBoss EAP 6.x or older, the approach is basically the same, see also here. GlassFish/Payara configuration example can be found here and WildFly configuration example can be found here.If you want to have control over reading/writing files yourself, then you need to create a
Servlet
for this which basically just gets anInputStream
of the file in flavor of for exampleFileInputStream
and writes it to theOutputStream
of theHttpServletResponse
.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 theContent-Length
header so that the client can calculate the download progress, otherwise it will be unknown. And, you should set theContent-Disposition
header toattachment
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.Here's a basic example of such a servlet:
When mapped on an
url-pattern
of for example/files/*
, then you can call it byhttp://example.com/files/image.png
. This way you can have more control over the requests than theDefaultServlet
does, such as providing a default image (i.e.if (!file.exists()) file = new File("/path/to/files", "404.gif")
or so). Also using therequest.getPathInfo()
is preferred aboverequest.getParameter()
because it is more SEO friendly and otherwise IE won't pick the correct filename during Save As.You can reuse the same logic for serving files from database. Simply replace
new FileInputStream()
byResultSet#getInputStream()
.See also:
您可以通过将图像放在固定路径(例如:/var/images 或 c:\images)中,在应用程序设置中添加设置(在我的示例中由 Settings.class 表示),然后加载它们来完成此操作像这样,在你的
HttpServlet
中:或者如果你想操作图像:
那么 html 代码将是
当然,您应该考虑提供不同的内容类型 - “image/jpeg”,例如基于文件扩展名。您还应该提供一些缓存。
此外,您可以使用此 servlet 来对图像进行质量重新缩放,方法是提供宽度和高度参数作为参数,并使用 image.getScaledInstance(w, h, Image.SCALE_SMOOTH),当然还要考虑性能。
You can do it by putting your images on a fixed path (for example: /var/images, or c:\images), add a setting in your application settings (represented in my example by the Settings.class), and load them like that, in a
HttpServlet
of yours:Or if you want to manipulate the image:
then the html code would be
<img src="imageServlet?imageName=myimage.png" />
Of course you should think of serving different content types - "image/jpeg", for example based on the file extension. Also you should provide some caching.
In addition you could use this servlet for quality rescaling of your images, by providing width and height parameters as arguments, and using
image.getScaledInstance(w, h, Image.SCALE_SMOOTH
), considering performance, of course.要求:从WEBROOT目录外部或本地磁盘访问静态资源(图像/视频等)
第1步:
在tomcat服务器的webapps下创建一个文件夹,假设文件夹名称为myproj
第2步:在myproj下创建一个WEB-INF文件夹,在该文件夹下创建一个简单的web.xml
代码,在web.xml下
创建上述目录结构两步
第三步:
现在,在 myproj.xml 中的以下位置
CODE 下创建一个名为 myproj.xml 的 xml 文件:
步骤 4:
4 A) 现在在硬盘的 E 驱动器中创建一个名为 myproj 的文件夹,并创建一个
名为 images 的新文件夹,并将一些图像放入图像文件夹
(e:myproj\images\)
让我们假设myfoto.jpg 放置在
e:\myproj\images\myfoto.jpg
下4 B) 现在在
e:\myproj\WEB-INF
中创建一个名为 WEB-INF 的文件夹> 并在 WEB-INF 文件夹中创建一个 web.xmlweb.xml 中的代码
第 5 步:
现在创建一个名为 index.html 的 .html 文档,并将其放在 e:\myproj 下,
代码位于 index.html 下
欢迎来到我的项目
上述步骤 4 和步骤 5 的目录结构如下
步骤 6:
现在启动 apache tomcat 服务器
步骤 7:
打开浏览器并键入如下 url,
然后显示中提供的内容index.html
第 8 步:
访问本地硬盘下的图像(webroot 之外)
Requirement : Accessing the static Resources (images/videos., etc.,) from outside of WEBROOT directory or from local disk
Step 1 :
Create a folder under webapps of tomcat server., let us say the folder name is myproj
Step 2 :
Under myproj create a WEB-INF folder under this create a simple web.xml
code under web.xml
Directory Structure for the above two steps
Step 3:
Now create a xml file with name myproj.xml under the following location
CODE in myproj.xml:
Step 4:
4 A) Now create a folder with name myproj in E drive of your hard disk and create a new
folder with name images and place some images in images folder
(e:myproj\images\)
Let us suppose myfoto.jpg is placed under
e:\myproj\images\myfoto.jpg
4 B) Now create a folder with name WEB-INF in
e:\myproj\WEB-INF
and create a web.xml in WEB-INF folderCode in web.xml
Step 5:
Now create a .html document with name index.html and place under e:\myproj
CODE under index.html
Welcome to Myproj
The Directory Structure for the above Step 4 and Step 5 is as follows
Step 6:
Now start the apache tomcat server
Step 7:
open the browser and type the url as follows
then u display the content which is provided in index.html
Step 8:
To Access the Images under your local hard disk (outside of webroot)
添加到 server.xml :
在 web.xml 中启用 dir 文件列表参数:
Add to server.xml :
Enable dir file listing parameter in web.xml :
这是我工作场所的故事:
- 我们尝试使用 Struts 1 和 Tomcat 7.x 上传多个图像和文档文件。
- 我们尝试将上传的文件写入文件系统、文件名和数据库记录的完整路径。
- 我们尝试在网络应用程序目录之外分离文件夹。 (*)
下面的解决方案非常简单,对要求有效 (*):
在文件
META-INF/context.xml
文件中包含以下内容:(例如,我的应用程序在
http://localhost:8080/ABC
运行,我的应用程序/项目名为ABC
)。(这也是文件
context.xml
的完整内容)(适用于 Tomcat 版本 7 或更高版本)
结果: 我们已创建 2 个别名。例如,我们将图像保存在:
D:\images\foo.jpg
并从链接或使用图像标签查看:
或
(我使用 Netbeans 7.x,Netbeans 似乎自动创建文件
WEB-INF\context.xml
)This is story from my workplace:
- We try to upload multiply images and document files use Struts 1 and Tomcat 7.x.
- We try to write uploaded files to file system, filename and full path to database records.
- We try to separate file folders outside web app directory. (*)
The below solution is pretty simple, effective for requirement (*):
In file
META-INF/context.xml
file with the following content:(Example, my application run at
http://localhost:8080/ABC
, my application / project namedABC
).(this is also full content of file
context.xml
)(works with Tomcat version 7 or later)
Result: We have been created 2 alias. For example, we save images at:
D:\images\foo.jpg
and view from link or using image tag:
or
(I use Netbeans 7.x, Netbeans seem auto create file
WEB-INF\context.xml
)如果您决定分派到
FileServlet
,那么您还需要context.xml
中的allowLinking="true"
以允许FileServlet
遍历符号链接。请参阅 http://tomcat.apache.org/tomcat-6.0-doc/配置/context.html
If you decide to dispatch to
FileServlet
then you will also needallowLinking="true"
incontext.xml
in order to allowFileServlet
to traverse the symlinks.See http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
如果您想使用JAX-RS(例如RESTEasy),请尝试以下操作:
使用
javax.ws.rs.core.Response
和com.google.common。 io.ByteStreams
If you want to work with JAX-RS (e.g. RESTEasy) try this:
using
javax.ws.rs.core.Response
andcom.google.common.io.ByteStreams
如果有人无法通过接受的答案解决他的问题,请注意以下注意事项:
提及
属性。localhost:
。 srcserver.xml
文件中自行创建context docBase
条目。if anyone not able to resolve his problem with accepted answer, then note these below considerations:
localhost:<port>
with<img> src
attribute.context docBase
entry on its own inside its localserver.xml
file.读取文件的InputStream并将其写入
ServletOutputStream
用于向客户端发送二进制数据。结果 URL 直接指向
src
属性。Read the InputStream of a file and write it to
ServletOutputStream
for sending binary data to the client.Result the URL directly to the
src
attibute.您可以编辑
conf
目录中的 2 个文件:首先,编辑
server.xml
文件:您将看到
有许多
标记。在名称为:“localhost”的
中,将
更改为:with:
docBase
是包含图像的目录的路径。path
:是显示图像时将添加到 url 的路径。您的目标将类似于:http://localhost:8080/images/image1.png
接下来,在default 编辑如下:
中编辑web.xml
文件,名称为:< code>当您启动 Tomcat 时,它将像图像服务器一样启动
希望有帮助
You can edit 2 files in the
conf
directory:First, edit
server.xml
file:You will see
<Engine></Engine>
has many<Host></Host>
tag.In the
<Host>
with name is: "localhost", change<Context>
to:with:
docBase
is the path to the directory containing your images.path
: is the path that will add to url when showing the image.Your target will like: http://localhost:8080/images/image1.png
Next, edit
web.xml
file, in the<servlet>
with name:<servlet-name>default</servlet-name>
edit like:It will start like an image server when you start Tomcat
Hope that it helps
我做的更简单。问题:CSS 文件具有指向 img 文件夹的 url 链接。获取 404。
我查看了 url,http://tomcatfolder:port/img/blablah.png ,它不存在。但是,这确实指向 Tomcat 中的 ROOT 应用程序。
所以我只是将 img 文件夹从我的 web 应用程序复制到该 ROOT 应用程序中。作品!
当然,不建议用于生产,但这是用于内部工具开发应用程序。
I did it even simpler. Problem: A CSS file had url links to img folder. Gets 404.
I looked at url, http://tomcatfolder:port/img/blablah.png, which does not exist. But, that is really pointing to the ROOT app in Tomcat.
So I just copied the img folder from my webapp into that ROOT app. Works!
Not recommended for production, of course, but this is for an internal tool dev app.