5

我在http://ip:8080/simple
下部署了一个 servlet 该 servlet 在包下a.b.c
我有一个a.b.resources名为的 html 页面Test.html

html 有一个img图像标签。

在我做的 servlet 中:

htmlFile = MyServlet.class.getResourceAsStream("/a/b/resources/Test.html");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
byte[] bytes=new byte[htmlFile.available()];
htmlFile.read(bytes);
resp.setContentLength(bytes.length);
writer.print(new String(bytes));
writer.flush();
writer.close();

html 页面出现在浏览器上,但在图像的位置我看到了它的alt描述。
我努力了:

<img alt="Company A" src="./CompanyLogo.jpg">

<img alt="Company A" src="/a/b/resources/CompanyLogo.jpg">

<img alt="Company A" src="CompanyLogo.jpg">

但这些都不起作用。
jpg 图像位于/a/b/c/resources 下,即与HTML 页面位于同一目录中。
我正在使用嵌入式码头。

我在这里搞什么鬼?

4

3 回答 3

7

浏览器正在尝试相对于当前请求 URI 解析这些资源(如您在浏览器地址栏中看到的)。这些资源当然不存在于您的公共 Web 内容中,因为您似乎已将它们放在类路径中。

为了解决这个问题,您真的需要解析HTML 并更改所有与域相关的src和/或, , , , ,等元素的href属性 <a>,以让它们指向一个 servlet,该 servlet 将这些资源从类路径流式传输到 HTTP回复。<img><base><link><script><iframe>

这有点工作,但Jsoup使它变得容易。这是一个假设您的 servlet 映射到/proxy/*.

String proxyURL = request.getContextPath() + "/proxy/";
InputStream input = MyServlet.class.getResourceAsStream("/a/b/resources" + request.getPathInfo());

if (request.getRequestURI().endsWith(".html")) { // A HTML page is been requested.
    Document document = Jsoup.parse(input, "UTF-8", null);

    for (Element element : document.select("[href]")) {
        element.attr("href", proxyURL + element.attr("href"));
    }

    for (Element element : document.select("[src]")) {
        element.attr("src", proxyURL + element.attr("src"));
    }

    response.setContentType("text/html;charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(document.html());
}
else { // Other resources like images, etc which have been proxied to this servlet.
    response.setContentType(getServletContext().getMimeType(request.getPathInfo()));
    OutputStream output = response.getOutputStream();
    byte[] buffer = new byte[8192];

    for (int length = 0; (length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length);
    }
}

input.close();

通过http://yourdomain:yourport/contextname/proxy/test.html打开它。

于 2011-09-12T15:43:52.303 回答
1

如果不实现将从资源文件中读取图像的 servlet,就无法做到这一点。尝试这个:

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
  byte[] bbuf = new byte[8192];
  resp.setContentType(req.getSession().getServletContext().getMimeType( req.getPathInfo()));
  InputStream in = MyImageServlet.class.getResourceAsStream("/"+req.getPathInfo());
  OutputStream op = resp.getOutputStream();
  int length;
  while ((in != null) && ((length = in.read(bbuf)) != -1)){
      op.write(bbuf,0,length);
      op.flush();
  }
  in.close();
  op.close();  
}

web.xml然后像这样注册它

<servlet-mapping>
  <servlet-name>fetchimage</servlet-name>
  <url-pattern>/fetchimage/*</url-pattern>
</servlet-mapping>

然后像这样使用它

<img alt="Company A" src="/fetchimage/a/b/resources/CompanyLogo.jpg">

您将需要实施大量错误检查(A LOT OF ERROR CHECKING,只是为了澄清:)),过滤路径以确保有人不能只使用相同的技术读取您的类文件,但对此有一些变化应该为你工作。

于 2011-09-11T19:00:07.207 回答
0

request.getRequestDispatcher("/a/b/Test.html").forward(request, response);

于 2011-09-11T18:51:08.417 回答