通过将静态数据存储在Web容器中来做到这一点不是问题,但是从Web容器外部存储和加载它们使我头疼。
我现在不希望使用像Apache这样的单独的Web服务器来提供静态数据。我也不喜欢将图像以二进制形式存储在数据库中的想法。
我已经看到一些建议,例如将图像目录作为指向Web容器外部目录的符号链接,但是这种方法会在Windows和* nix环境下都可以工作吗? br />
#1 楼
我已经看到一些建议,例如将图像目录作为指向Web容器外部目录的符号链接,但是这种方法在Windows和* nix环境下都可以使用吗?如果您遵循* nix文件系统路径规则(即,您仅在
/path/to/files
中使用正斜杠),则它也将在Windows上运行,而无需费心处理File.separator
字符串串联。但是,只能在与调用该命令的位置相同的工作磁盘上对其进行扫描。因此,例如,如果在C:
上安装了Tomcat,则/path/to/files
实际上将指向C:\path\to\files
。如果文件都位于Web应用程序外部,并且您想让Tomcat的
DefaultServlet
来处理它们,那么您基本上要做的就是在Tomcat中,是在/conf/server.xml
标签内的<Host>
中添加以下Context元素: 。对于基于Tomcat的服务器(例如JBoss EAP 6.x或更早版本),方法基本相同,另请参见此处。 GlassFish / Payara配置示例可以在此处找到,WildFly配置示例可以在此处找到。如果您想自己控制文件的读写,则需要为此创建一个
<Context docBase="/path/to/files" path="/files" />
,基本上可以得到一个http://example.com/files/...
以Servlet
之类的文件格式添加文件,并将其写入到InputStream
的FileInputStream
中。在响应上,您应该设置
OutputStream
标头,以便客户端知道要与提供的文件关联的应用程序。并且,您应该设置HttpServletResponse
标头,以便客户端可以计算下载进度,否则它将是未知的。并且,如果需要“另存为”对话框,则应将Content-Type
标头设置为Content-Length
,否则客户端将尝试内联显示它。最后,只需将文件内容写入响应输出流即可。这是这种servlet的基本示例:这样,您可以比
Content-Disposition
更好地控制请求,例如提供默认图片(即attachment
左右)。在url-pattern
之前,还优先使用/files/*
,因为它对SEO更友好,否则IE在另存为时将不会选择正确的文件名。只需将http://example.com/files/image.png
替换为DefaultServlet
。希望这会有所帮助。静态资源Servlet(支持HTTP缓存)
如何在JSP页面中从数据库检索和显示图像?
如何使用Servlet来流化音频/视频文件,例如MP3,MP4,AVI等
#2 楼
您可以通过将图像放在固定路径上(例如:/ var / images或c:\ images),在应用程序设置中添加一个设置(在我的示例中由Settings.class表示)来进行加载像这样,在您自己的HttpServlet
中:String filename = Settings.getValue("images.path") + request.getParameter("imageName")
FileInputStream fis = new FileInputStream(filename);
int b = 0;
while ((b = fis.read()) != -1) {
response.getOutputStream().write(b);
}
或者如果您想操作图像: />,那么html代码将是
<img src="imageServlet?imageName=myimage.png" />
当然,您应该考虑提供不同的内容类型-例如“ image / jpeg”,例如基于文件扩展名。此外,您还应该提供一些缓存。
此外,您还可以通过提供width和height参数作为参数,并使用
image.getScaledInstance(w, h, Image.SCALE_SMOOTH
),当然也要考虑性能,从而可以将此servlet用于图像的质量缩放。 br />评论
您确实不需要Java 2D API,它只会不必要地增加更多开销。只需读取InputStream并写入OutputStream。
– BalusC
09年11月28日在11:44
是的,我以重新缩放和其他操作的想法开始了响应,但最终简化了它。
– Bozho
09年11月28日在11:59
#3 楼
添加到server.xml中: <Context docBase="c:/dirtoshare" path="/dir" />
在web.xml中启用目录文件列表参数:
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
评论
通过更改web.xml,我可以获取文件列表,以便将其发送到选择框?
– Tomasz Waszczyk
16-11-21在7:54
此更改将在tomcat的web.xml中,而不是您的应用程序中
–vsingh
17年11月13日在21:24
谢谢你!是否需要在web.xml中启用dir文件列表参数?
– dariru
18年9月7日在2:52
#4 楼
要求:从WEBROOT目录外部或从本地磁盘访问静态资源(图像/视频等)步骤1:
在tomcat服务器的webapps下创建一个文件夹。让我们说文件夹名称为myproj
步骤2:在myproj下,创建一个WEB-INF文件夹,然后在web.xml下创建一个简单的web.xml
代码。 />
<web-app>
</web-app>
以上两个步骤的目录结构
c:\programfile\apachesoftwarefoundation\tomcat\...\webapps
|
|---myproj
| |
| |---WEB-INF
| |
|---web.xml
步骤3:
现在创建一个xml位于以下位置的名称为myproj.xml的文件
c:\programfile\apachesoftwarefoundation\tomcat\conf\catalina\localhost
myproj.xml中的代码:
<Context path="/myproj/images" docBase="e:/myproj/" crossContext="false" debug="0" reloadable="true" privileged="true" />
步骤4:
4 A)现在,在硬盘的E驱动器中创建一个名为myproj的文件夹,并创建一个带有名称图像的新
文件夹,并将一些图像放置在图像中文件夹
(e:myproj\images\)
让我们假设myfoto.jpg放在
e:\myproj\images\myfoto.jpg
下4 B)现在在
e:\myproj\WEB-INF
中创建一个名称为WEB-INF的文件夹,并在WEB中创建一个web.xml -在F文件夹web.xml中的代码
<web-app>
</web-app>
步骤5:现在,创建一个名称为index.html的.html文档,并将其放在e下:\ myproj
index.html下的代码
欢迎使用Myproj
目录结构上述步骤4和步骤5如下所示
E:\myproj
|--index.html
|
|--images
| |----myfoto.jpg
|
|--WEB-INF
| |--web.xml
步骤6:现在启动apache tomcat服务器
步骤7:打开浏览器并按如下所示键入URL
http://localhost:8080/myproj
,然后显示index.html中提供的内容。
步骤8:访问本地硬盘(位于Webroot外部)下的图像
http://localhost:8080/myproj/images/myfoto.jpg
评论
您能建议我如何为动态值做同样的事情吗?我的意思是我想将data(xml)写入本地目录或和并在我的jsp页面中读取它。有什么方法可以写入托管到目录的服务器,以便我可以使用上述过程访问它们?
– Sudip7
2014年11月21日在13:03
尽管我可以正常运行index.html文件,但Web浏览器中无法显示图像
–rogerwar
2015年5月29日3:00
我的错误帖子可以正常工作,我只是忘了把/放在E:/ myproj的末尾,我将其更改为E:/ myproj /及其工作正常,谢谢@sbabamca
–rogerwar
15年5月29日在3:08
嗨,感谢您的帖子,这非常有用。在这里,我希望通过接口将文件上传到该特定目录。我希望同样启用POST方法。有人可以帮我吗?
–vicky
15年6月13日在10:58
#5 楼
这是我工作场所的故事:-我们尝试使用Struts 1和Tomcat 7.x上传多张图片和文档文件。
-我们尝试将上传的文件写入文件系统,文件名和完整路径。数据库记录。
-我们尝试将Web应用程序目录之外的文件夹分开。 (*)
以下解决方案非常简单,可以有效地满足要求(*):
文件
META-INF/context.xml
中的文件内容如下:(示例应用程序在
http://localhost:8080/ABC
上运行,我的应用程序/项目名为ABC
)。(这也是
context.xml
文件的完整内容)或更高版本)结果:我们已经创建了2个别名。例如,我们将图像保存在:
D:\images\foo.jpg
,并从链接或使用图像标签查看: br />
(我使用Netbeans 7.x,Netbeans似乎自动创建了文件
WEB-INF\context.xml
)#6 楼
如果您决定分派给FileServlet
,则还需要allowLinking="true"
中的context.xml
,以允许FileServlet
遍历符号链接。请参阅http://tomcat.apache.org/tomcat-6.0-doc/ config / context.html
#7 楼
如果任何人都无法通过接受的答案解决他的问题,请注意以下注意事项:无需使用
localhost:<port>
属性提及<img> src
。 eclipse之外,因为eclipse会在其本地context docBase
文件内自行创建server.xml
条目。#8 楼
读取文件的InputStream并将其写入ServletOutputStream
,以将二进制数据发送到客户端。 .png')。,您可以使用GridFS获得InputStream。
br />
直接将URL生成到
@WebServlet("/files/URLStream")
public class URLStream extends HttpServlet {
private static final long serialVersionUID = 1L;
public URLStream() {
super();
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File source = new File("D:\SVN_Commit.PNG");
long start = System.nanoTime();
InputStream image = new FileInputStream(source);
/*String fileID = request.getParameter("id");
System.out.println("Requested File ID : "+fileID);
// Mongo DB GridFS - https://stackoverflow.com/a/33544285/5081877
image = outputImageFile.getInputStream();*/
if( image != null ) {
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
ServletOutputStream sos = response.getOutputStream();
try {
bin = new BufferedInputStream( image );
bout = new BufferedOutputStream( sos );
int ch =0; ;
while((ch=bin.read())!=-1) {
bout.write(ch);
}
} finally {
bin.close();
image.close();
bout.close();
sos.close();
}
} else {
PrintWriter writer = response.getWriter();
writer.append("Something went wrong with your request.");
System.out.println("Image not available.");
}
System.out.println("Time taken by Stream Copy = "+(System.nanoTime()-start));
}
}
礼节。 src
#9 楼
如果要使用JAX-RS(例如RESTEasy),请尝试以下操作:@Path("/pic")
public Response get(@QueryParam("url") final String url) {
String picUrl = URLDecoder.decode(url, "UTF-8");
return Response.ok(sendPicAsStream(picUrl))
.header(HttpHeaders.CONTENT_TYPE, "image/jpg")
.build();
}
private StreamingOutput sendPicAsStream(String picUrl) {
return output -> {
try (InputStream is = (new URL(picUrl)).openStream()) {
ByteStreams.copy(is, output);
}
};
}
使用
javax.ws.rs.core.Response
和com.google.common.io.ByteStreams
#10 楼
我做得更简单。问题:CSS文件具有指向img文件夹的URL链接。获取404。我查看了不存在的URL http:// tomcatfolder:port / img / blablah.png。但是,这实际上是指向Tomcat中的ROOT应用程序。
所以我只是将img文件夹从我的Web应用程序复制到了该ROOT应用程序中。作品!
当然不建议用于生产,但这是针对内部工具开发应用程序的。
评论
@SalutonMondo:省力的方式。
– BalusC
2015年2月11日下午13:30
@BalusC,我尝试了此操作:Windows中的
– ACV
2015年9月12日在16:50
在Windows上,应为:
– ACV
2015年9月12日在16:52
并在执行以下操作时获取HTTP Status 404-/ images /:http:// localhost:8080 / images /,但是从tmp下运行特定文件:http:// localhost:8080 / images / Tulips.jpg可以
– ACV
2015年9月12日16:55
这样,如果我将图像放在文件夹中,除非重新启动服务器,否则图像的链接将给出响应404,请问有什么原因吗?
– Mateus Viccari
16年4月1日在12:28