如何从 Java Servlet 将文件中的图像作为 HTML <img> 输出?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36375143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:20:58  来源:igfitidea点击:

How to output an image on file as an HTML <img> from a Java Servlet?

javahtmlservlets

提问by Abhishek Divekar

I have a servlet, Starter.java, in whose doGet() method I use a PrinterWriter object to print HTML.

我有一个 servlet Starter.java,在它的 doGet() 方法中我使用 PrinterWriter 对象来打印 HTML。

I have an image file: C:/.../Entertainment_mgmt/src/images/logo.png(inside my project), which I would like to display a Servlet page which I fetch from my localhost, at localhost:8084/Starter. The page also has other HTML structures, which I would like to retain (that is, I would like to fit the image in a on a small section of the screen). Simply outputting <img src="C:/.../Entertainment_mgmt/src/images/logo.png" />to HTML does not seem to work.

我有一个图像文件:(C:/.../Entertainment_mgmt/src/images/logo.png在我的项目中),我想显示一个从本地主机获取的 Servlet 页面,位于localhost:8084/Starter. 该页面还有其他 HTML 结构,我想保留这些结构(也就是说,我想将图像放在屏幕的一小部分中)。简单地输出<img src="C:/.../Entertainment_mgmt/src/images/logo.png" />到 HTML 似乎不起作用。

I've not performed any manual servlet mapping and I haven't changed any of Tomcat's configuration files.

我没有执行任何手动 servlet 映射,也没有更改任何 Tomcat 的配置文件。

enter image description here

在此处输入图片说明

I have checked many similar posts, but I just can't seem to get a hang of it.

我查过很多类似的帖子,但我似乎无法掌握它。

EDIT: I see that this post has been marked as a duplicate. I feel that this post still has significance due to the simple fact that other programmers might make the same mistake I did (regarding Tomcat serving images along with pages). Moreover, this provides a solution that does not require changing of Tomcat's /conf/server.xmlfile

编辑:我看到这篇文章已被标记为重复。我觉得这篇文章仍然具有重要意义,因为其他程序员可能会犯同样的错误(关于 Tomcat 与页面一起提供图像)。而且,这提供了一个不需要更改Tomcat/conf/server.xml文件的解决方案

回答by Abhishek Divekar

Okay so I figured out the answer. It turns out that to load an image, you actually need Java code to write out the binary data via a BufferedOutputStream (being a total newbie, I had thought that Tomcat would take care of that for me).

好的,所以我想出了答案。事实证明,要加载图像,您实际上需要 Java 代码通过 BufferedOutputStream 写出二进制数据(作为一个新手,我原以为 Tomcat 会为我处理这些)。

Concretely, you need a servlet to actually convert a path like "/images/logo.jpg" in your HTML into a usable image. The servlet is called via a servlet mapping of /images/* to the servlet. By extracting the * part of /images/* , we are able to get the exact image name, and then the servlet can load it.

具体来说,您需要一个 servlet 来实际将 HTML 中像“/images/logo.jpg”这样的路径转换为可用的图像。通过 /images/* 到 servlet 的 servlet 映射调用 servlet。通过提取 /images/* 的 * 部分,我们能够获得确切的图像名称,然后 servlet 可以加载它。

Here's the servlet mapping (to be added to WEB-INF/web.xml):

这是 servlet 映射(要添加到WEB-INF/web.xml):

...
<servlet>
    <servlet-name>DisplayImage</servlet-name>
    <servlet-class>servlets.DisplayImage</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>DisplayImage</servlet-name>
    <url-pattern>/images/*</url-pattern>
</servlet-mapping>
...

Note that in my project, DisplayImage is found in C:/.../Entertainment_mgmt/src/servlets/DisplayImage.java.

请注意,在我的项目中,DisplayImage 位于C:/.../Entertainment_mgmt/src/servlets/DisplayImage.java.

Of course, you can add whatever you want in your mapping. The mapping is what is seen in the URL, as in localhost:8040/images/logo.jpgor inside an HTML page as <img src="/images/logo.jpg" />. From the point of servlets, both are the same thing. As per the mapping above, both are handled by the servlet DisplayImage.

当然,您可以在映射中添加任何您想要的内容。映射是在 URL 中看到的内容,如在localhost:8040/images/logo.jpgHTML 页面中或内部作为<img src="/images/logo.jpg" />. 从 servlet 的角度来看,两者是一回事。根据上面的映射,两者都由 servlet DisplayImage 处理。

I found some code for the DisplayImage servlet here. I've modified it a bit:

我在这里找到了 DisplayImage servlet 的一些代码。我稍微修改了一下:

package servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DisplayImage extends HttpServlet {
    public final String imagesBase = "F:\Workspaces\Java\Projects\Entertainment_mgmt\src\images/";

    public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
        String URLAfterWebDomain = request.getRequestURI();

        //Only accept mappings as src="/images/whatever.jpg", even if web.xml has other mappings to this servlet.
        if(URLAfterWebDomain.startsWith("/images/") == false)   
            return;

        //get the image name, or even directory and image, e.g. /images/music/beethoven.jpg:
        String relativeImagePath = URLAfterWebDomain.substring("/images/".length());  //will get "music/beethoven.jpg"

        System.out.println("\nFetching image from "+imagesBase+relativeImagePath);
        response.setContentType("image/jpeg"); //as far as I know, this works for PNG as well. You might want to change the mapping to /images/*.jpg if it's giving problems

        ServletOutputStream outStream;
        outStream = response.getOutputStream();
        FileInputStream fin = new FileInputStream(imagesBase+relativeImagePath);

        BufferedInputStream bin = new BufferedInputStream(fin);
        BufferedOutputStream bout = new BufferedOutputStream(outStream);
        int ch =0; ;
        while((ch=bin.read())!=-1)
            bout.write(ch);

        bin.close();
        fin.close();
        bout.close();
        outStream.close();
    }
}

You can set imagesBaseto anyfolder on your computer, it doesn't have to be in your project folder. You can also change the name of the /images/folder to /pics/or whatever.

您可以设置imagesBase为计算机上的任何文件夹,它不必在您的项目文件夹中。您还可以将/images/文件夹的名称更改为/pics/或其他。

Now, whenever I put an <img>tag in an HTML, I can use src="/images/whatever.jpg"attribute to call the DisplayImage servlet and show the image. That image can then be repositioned, etc.

现在,每当我<img>在 HTML 中放置标签时,我都可以使用src="/images/whatever.jpg"属性来调用 DisplayImage servlet 并显示图像。然后可以重新定位该图像等。

This can even be done inside other servlets which write out HTML. In that case, the servlets are called independently and output over HTTP independently (this is why in some web pages, the text loads first and the image loads later).

这甚至可以在写出 HTML 的其他 servlet 中完成。在这种情况下,servlet 被独立调用并通过 HTTP 独立输出(这就是为什么在某些网页中,首先加载文本,然后加载图像)。

回答by Sandeep Sukhija

The image path you are providing is a absolute file path. The web resources are not accessed over the normal file path over the network, they are referred by the relative path from the webapp deployed on webserver.

您提供的图像路径是绝对文件路径。Web 资源不是通过网络上的普通文件路径访问的,而是由部署在 Web 服务器上的 Web 应用程序的相对路径引用。

You can put your images folder in a webapp base folder of the webserver and access the image using localhost:8084/images/logo.png

您可以将图像文件夹放在网络服务器的 webapp 基本文件夹中,并使用 localhost:8084/images/logo.png