在我的tomcat文件夹的server.xml
内,我在<Host>
标记下有一个虚拟文件夹:
<Context docBase="C:\app_files\" path="/app_files"/>
所以我可以通过网址http://localhost:8080/app_files/some_file.jpg
访问此文件夹中的文件但是只有在服务器启动之前图像或文件已经存在的情况下,这才有效。如果我转到指向服务器启动后创建的映像的URL,则会出现404错误。重新启动服务器后,图像正确加载。
如何解决这个问题?
答案 0 :(得分:0)
尝试将属性autoDeploy="true"
添加到您的上下文配置中,这将告诉catalina监控您的文档库位置以进行更改
答案 1 :(得分:0)
如果您使用Tomcat应用程序管理器,您可以取消部署/部署单个应用程序而无需重新启动整个服务器(并且不会影响其他Web应用程序),或者更残酷的是,您可以从webapps目录替换所需的战争(再次取消部署/部署随之而来)。如果您必须保证应用程序的正常运行时间,即使在这种情况下您也必须进行并行部署(here a guide for tomcat 8)
答案 2 :(得分:0)
我实际上设法做了我想要的,而不使用server.xml上的Context。 它基于BalusC's solution通过servlet提供静态文件 方法如下:
public String imageUrl;
public void createAndShowImage() {
try {
String imageName = "/nice_images_folder/cool_image.jpg";
File imageFile = new File(System.getenv("MANAGEMENT_FILES") + imageName);
//Here goes your logic to create the file
createImage(imageFile);
//Here i use a fixed URL, you can do it as you see fit
this.imageUrl = "http://localhost:8080/MyCoolApp/" + CoolFileServlet.BASE_URL + imageName + "?delete=true";
} catch (Exception e) {
e.printStackTrace();
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name="CoolFileServlet", urlPatterns={CoolFileServlet.BASE_URL + "*"})
public class CoolFileServlet extends HttpServlet {
public static final String BASE_URL = "/shiny_happy_files/";
private static final int DEFAULT_BUFFER_SIZE = 10240;
private String filePath;
public void init() throws ServletException {
this.filePath = System.getenv("MANAGEMENT_FILES");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String requestedFile = request.getPathInfo();
if (requestedFile == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
if (!file.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
String contentType = getServletContext().getMimeType(file.getName());
if (contentType == null) {
contentType = "application/octet-stream";
}
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
try {
if ("true".equals(request.getParameter("delete"))) {
if (!file.delete()) {
throw new RuntimeException("File could not be deleted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
请注意,访问时可以在url中传递参数delete = true,在恢复后立即将其删除(如果不再需要它)。
在我的情况下,我需要在用户执行某些操作后在页面上显示图像,所以我所要做的就是显示图像网址:
<h:graphicImage url="#{myManagedBean.imageUrl}"/>
就是这样,您可以使用此servlet为任何类型的文件提供服务,它将立即返回您想要的文件,并且文件将在服务器重新启动/重新部署之间保持活动状态(如果未通过{{1}删除它}。
答案 3 :(得分:0)
如果您希望使用其他方法,也可以通过在指定媒体类型的同时在返回IOUtils对象的控制器中映射函数,然后在img的src中调用该函数的URL,来实现此目的。
@ResponseBody
@RequestMapping(value="/load_photo", params = {"myPhoto"}, method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public byte[] loadPhoto(@RequestParam(value = "myPhoto") String myPhoto) throws IOException {
File file = new File(servletContext.getRealPath("")+Constants.PATH_TO_FILE+myPhoto);
FileInputStream fis = new FileInputStream(file);
return IOUtils.toByteArray(fis);
}
然后您在JSP中调用img:
<img class="photo" src="/app/controller/load_photo?myPhoto=${myPhoto}">
借助此功能,您可以提供动态生成的图像。