我有简单的java web应用程序。
index.html文件的链接跟随路径“test / aaa”
<html>
<head>
<title></title>
</head>
<body>
<a href="test/aaa"> click </a>
</body>
</html>
这是web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>web.Servlet1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>web.Servlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/haha/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
所以路径“test / aaa”导致servlet web.Servlet1
package web;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet1 extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
System.out.println("1");
RequestDispatcher view = request.getRequestDispatcher("/test.jsp");
view.forward(request, response);
System.out.println("2");
}
}
Servlet1只是导致test.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!</h1>
<img src="haha/bbb">
</body>
</html>
test.jsp只显示“Hello World!”以及“定位”路径“haha / bbb”的图像
在web.xml中设置路径“haha / bbb”导致servlet web.Servlet2生成并返回简单图像
package web;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet2 extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
System.out.println("3");
BufferedImage image = new BufferedImage(256, 256,
BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = image.createGraphics();
imageGraphics.setColor(Color.BLACK);
imageGraphics.fillRect(10, 10, 200, 200);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
response.setContentType("image/png");
response.setContentLength(imageInByte.length);
response.getOutputStream().write(imageInByte);
System.out.println("4");
}
}
我希望在浏览器中看到一个图像,并在控制台中看到这个输出:
1
2
3
4
相反,我没有在浏览器和控制台中看到图像,我看到了这一点:
1
2
1
2
此外,如果我在浏览器中手动转到路径“haha / bbb”,我会在控制台中获取图像和“34”
有人可以说明为什么web.Servlet1调用2次而web.Servlet2根本没有被调用?
答案 0 :(得分:4)
请记住,当您致电Servlet1
RequestDispatcher view = request.getRequestDispatcher("/test.jsp");
view.forward(request, response);
您的网址无法更改,因此它仍然是
server/YourProject/test/aaa
这意味着当浏览器加载的代码由test.jsp
生成时包括
<img src="haha/bbb">
这条路径将指的是
server/YourProject/test/haha/bbb
^^^^^^^^^^^^^^^^^^^^^^^^
since this part is location of `aaa`, `haha/bbb` will be simply added to it.
(由于/test/*
映射,Servlet1将需要处理此调用,这解释了控制台中的其他1 2
输出
不要
server/YourProject/haha/bbb
要解决此问题,请不要使用相对路径,而应使用资源的完整路径。您可以在EL
的帮助下创建它<img src="${pageContext.request.contextPath}/haha/bbb">
${pageContext.request.contextPath}/
返回server/projectName
答案 1 :(得分:0)
首先,您应该非常小心地使用JSP / Servlet中的相对URL。
问题是servlet1正在提供URL&lt; context_path&gt; / test / aaa,您可以从中将内部重定向到test.jsp。
test.jsp在servlet1的主体和servlet1的请求(GET /&lt; context_path&gt; / test / aaa)的上下文中处理。浏览器会看到相对网址:
<img src="haha/bbb">
并将其展开为/&lt; context_path&gt; / test / aaa / haha / bbb。然后浏览器生成GET /&lt; context_path&gt; / test / aaa / haha / bbb并收到404 Not Found。
所以要修复你的代码替换
<img src="haha/bbb">
与
<img src="/haha/bbb">
或更好 - 启用taglib网址并打印:
<img src="<c:url value='/haha/bbb' />" >
使用taglibs制作URL比处理ContextPath更安全,更容易
答案 2 :(得分:0)
您使用的是相对网址。如果缺少runtime.exec(CONTROL_G); // hmm
元素,则客户端浏览器会根据请求URL解析它们,而请求URL不包含有关服务器端任何内部处理的信息。
因此,如果客户端请求URL <base>
,并且它收到的HTML包含元素http://test/aaa
,它会根据请求URL解析图像源URL以获取<img src="haha/bbb">
。此URL映射到servlet1(因此控制台输出中的第二个http://test/haha/bbb
,1
),但servlet1不提供图像,因此不显示任何图像。
现在最简单的解决方法是让JSP在其返回的页面的2
中包含适当的<base>
元素。或者,您可以指定绝对源URL,或者至少指定相对于文档根目录(<head>
)或相对于上下文根的URL。