Правильно напишите HTML-страницу в ответе сервлета. - PullRequest
4 голосов
/ 11 сентября 2011

У меня есть сервлет, развернутый в http://ip:8080/simple
Сервлет в упаковке a.b.c
У меня есть HTML-страница в a.b.resources с именем Test.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.

Что я тут возую?

Ответы [ 3 ]

6 голосов
/ 12 сентября 2011

Браузер пытается разрешить эти ресурсы относительно текущего URI запроса (как вы видите в адресной строке браузера). Эти ресурсы, конечно же, не существуют в вашем общедоступном веб-контенте, поскольку вы, кажется, разместили их в пути к классам.

Чтобы решить эту проблему, вам действительно нужно проанализировать HTML и изменить все относящиеся к домену src и / или href атрибуты <a>, <img>, * 1009 Элементы *, <link>, <script>, <iframe> и т. Д., Позволяющие им указывать сервлет, который направляет эти ресурсы из пути к классам в ответ HTTP.

Это немного работы, но 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.

1 голос
/ 11 сентября 2011

Нет способа сделать это без реализации сервлета, который будет считывать образ из файла ресурсов.Попробуйте это:

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

Вам потребуетсяреализовать много проверок на ошибки (МНОГО ПРОВЕРКИ ОШИБОК, просто чтобы уточнить :)), отфильтровать пути, чтобы убедиться, что кто-то не может просто читать ваши файлы классов, используя ту же технику, но некоторые варианты этого должны работать для вас.

0 голосов
/ 11 сентября 2011

request.getRequestDispatcher ("/ a / b / Test.html"). Forward (запрос, ответ);

...