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

时间:2016-04-02 15:28:23

标签: java html servlets

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

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

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

enter image description here

我已经检查了许多类似的帖子,但我似乎无法掌握它。

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

的解决方案

2 个答案:

答案 0 :(得分:2)

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

具体而言,您需要一个servlet来实际转换路径,如&#34; /images/logo.jpg"在您的HTML中成为可用的图像。 servlet通过/ images / *的servlet映射到servlet来调用。通过提取/ images / *的*部分,我们可以获得确切的图像名称,然后servlet可以加载它。

这里是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>
...

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

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

我找到了DisplayImage servlet here的一些代码。我对它进行了一些修改:

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();
    }
}

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

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

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

答案 1 :(得分:0)

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

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

访问图片