我在http://ip:8080/simple下部署了一个servlet
servlet位于包a.b.c
下
我在a.b.resources
中有一个名为Test.html
的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页面位于同一目录中 我正在使用嵌入式Jetty。
我在这里搞什么?
答案 0 :(得分:6)
浏览器正在尝试解析与当前请求URI相关的资源(如浏览器地址栏中所示)。当然,您的公共Web内容中不存在这些资源,因为您似乎已将它们放在类路径中。
为了解决这个问题,您确实需要解析 HTML并更改src
的所有与域相关的href
和/或<a>
属性,<img>
,<base>
,<link>
,<script>
,<iframe>
等元素让它们指向一个servlet,它将这些资源从类路径流式传输到HTTP响应。
这有点工作,但Jsoup让事情变得简单。这是一个假设您的servlet映射到/proxy/*
的URL模式。
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();
答案 1 :(得分: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">
你需要实现大量的错误检查(很多错误检查,只是为了澄清:)),过滤路径以确保有人不能只使用相同的技术读取你的类文件,但有些对此的变化应该适合你。
答案 2 :(得分:0)
request.getRequestDispatcher(“/ a / b / Test.html”)。forward(request,response);