在我的网络应用程序中,我有一个包含一些信息的主页面。该页面由servlet和相应的jsp文件创建。我的Web应用程序中的几乎所有其他页面都必须包含与主页相同的信息以及一些附加信息。我不想要dublicate代码,所以我想在其他jsp文件中使用main servlet的输出。以下是我尝试完成的一个简单示例。
这是 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>app.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>app.Servlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/servlet2</url-pattern>
</servlet-mapping>
</web-app>
这是 java 文件:
servlet1.java
package app;
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 {
request.setAttribute("servletAttribute", 1);
RequestDispatcher view = request.getRequestDispatcher("/servlet1.jsp");
view.forward(request, response);
}
}
servlet2.java
package app;
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 Servlet2 extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("servletAttribute", 2);
RequestDispatcher view = request.getRequestDispatcher("/servlet2.jsp");
view.forward(request, response);
}
}
这是 jsp 文件:
servlet1.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
servlet1
<%
Integer servletAttribute = (Integer)request.getAttribute("servletAttribute");
out.print("<br>servletAttribute:" + servletAttribute);
%>
servlet2.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<jsp:include page="/servlet1" />
servlet2
<%
Integer servletAttribute = (Integer)request.getAttribute("servletAttribute");
out.print("<br>servletAttribute:" + servletAttribute);
%>
所以servlet2.jsp必须显示servlet1的输出。它显示它,但它不显示来自servlet2的附加信息。我在日志文件中收到此错误:
org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [servlet2] in context with path [/WebApplication3] threw exception [java.lang.IllegalStateException: Exception occurred when flushing data] with root cause
java.io.IOException: Stream closed
因为我明白这个错误出现是因为当servlet2.jsp调用“/ servlet1”时servlet1向客户端发送响应并且servlet2.jsp不再有会话。
所以我的问题是 - 如何修复我的代码来完成我想要的?是否可以将某些servlet的输出包含到某个jsp文件中?如果有可能,这是一种好的还是坏的做法?
答案 0 :(得分:3)
在servlet2.jsp中:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<jsp:include page="/servlet1" />
在servlet2.jsp中,您使用了jsp:include。 它包括servlet1响应的响应。
但 servlet1 ,它会将响应转发给另一个jsp。所以发生异常。
为了避免这种情况,在Servlet1类中应该使用 view.include(request,response); 而不是 view.forward(request,response); 。
package app;
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 {
request.setAttribute("servletAttribute", 1);
RequestDispatcher view = request.getRequestDispatcher("/servlet1.jsp");
view.include(request, response);
}
}