Write the HTML page in the servlet response properly

I have a servlet deployed under http: // ip: 8080 / simple
The servlet is under the abc package
I have an html page in abresources called Test.html .

In html there is an img tag for the image.

In the servlet, I do:

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

The html page appears in the browser, but instead of the image, I see its description alt .
I tried:

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

But none of these works.
The jpg image is located in / a / b / c / resources, i.e. in the same directory as the HTML page.
I use the built-in Jetty.

What am I messing around here?

+4
source share
3 answers

The browser tries to resolve these resources relative to the current request URI (as you see in the address bar of the browser). These resources, of course, do not exist in your public web content, as you seem to have put them in the classpath.

To solve this problem, you really need to parse the HTML and change all src and / or href attributes for the domain <a> , <img> , <base> , <link> , <script> , <iframe> , etc. so that they point to a servlet that passes these resources from the path to the HTTP response.

This works a bit, but Jsoup makes things easier. Here is an example that assumes your servlet is displayed on the URL /proxy/* pattern.

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

Open it http: // yourdomain: yourport / contextname / proxy / test.html .

+6
source

It is impossible to do this without implementing a servlet that will read an image from a resource file. Try the following:

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

then register it in web.xml so that

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

and then use it like that

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

You will need to do a big error check (MANY ERROR CHECKS, just for clarification :)), filter the paths to make sure that someone cannot just read your class files using the same technique, but some variation on this should work for you.

+1
source

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

0
source

All Articles