如何将 servlet 输出包含到 jsp 文件

How include servlet output to jsp file

提问人:nik 提问时间:2/17/2016 更新时间:2/17/2016 访问量:13702

问:

在我的 Web 应用程序中,我有一个包含一些信息的主页。此页面由 servlet 和相应的 jsp 文件创建。我的 Web 应用程序中的几乎所有其他页面都必须包含与主页相同的信息以及一些附加信息。我不想要 dublicate 代码,所以我想在其他 jsp 文件中使用主 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 文件中?如果可能的话,这是好的做法还是坏的做法?

Java JSP Servlet

评论

0赞 ewanc 2/17/2016
真的有必要有两个单独的 servlet,每个 servlet 都只是转发到一个 JSP 页面吗?难道不能只使用一个 servlet 并根据需要将请求路由到 JSP 页面吗?
0赞 BalusC 2/17/2016
这是一个非常奇怪的设计,表明某个地方存在根本性的误解。也许您的 servlet 只是做得“太多”,以至于需要将共享代码重构为一个独立的 Java 类,而该类又可以被两个 servlet 导入/使用?最终,只需调用一个 servlet,该 servlet 又会转发到所需的 JSP,而不是相反。参见 a.o. stackoverflow.com/q/5649722

答:

4赞 CrawlingKid 2/17/2016 #1

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