5

http://ip:8080/simpleの下にデプロイされたサーブレットがあり
ます サーブレットはパッケージの下にあります名前付きa.b.c
の html ページがあります。 a.b.resourcesTest.html

html にはimg画像のタグがあります。

私が行うサーブレットでは:

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 ページと同じディレクトリにあります。
組み込みの Jetty を使用しています。

私はここで何をいじっていますか?

4

3 に答える 3

7

ブラウザーは、現在の要求 URI に関連するこれらのリソースを解決しようとしています (ブラウザーのアドレス バーに表示されているように)。もちろん、これらのリソースは、クラスパスに配置したように見えるため、公開 Web コンテンツには存在しません。

これを解決するには、HTMLを解析し、、、、、などの要素のすべてのドメイン関連srcおよび/またはhref属性を 変更して、これらのリソースをクラスパスから HTTP にストリーミングするサーブレットを指すようにする必要があります。応答。<a><img><base><link><script><iframe>

少し手間がかかりますが、 Jsoupを使えば簡単です。これは、サーブレットが の URL パターンにマップされていることを前提とした例です/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

リソース ファイルからイメージを読み取るサーブレットを実装せずにこれを行う方法はありません。これを試して:

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">

多くのエラーチェックを実装する必要があります(明確にするために多くのエラーチェックを行います:))、パスをフィルタリングして、誰かが同じ手法を使用してクラスファイルを読み取れないようにしますが、これにはいくつかのバリエーションがありますあなたのために働くはずです。

于 2011-09-11T19:00:07.207 に答える
0

request.getRequestDispatcher("/a/b/Test.html").forward(リクエスト、レスポンス);

于 2011-09-11T18:51:08.417 に答える