0
votes

In my web application I have a main page that contain some information. This page is created by servlet and corresponding jsp file. Almost all other pages in my web application must contain the same information as main page plus some addition information. I don't want dublicate code, so I want to use output of main servlet in other jsp files. Below is a simple example of what I try to accomplish.

This is web.xml file:

<?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>

This is java files:

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

This is jsp files:

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

So servlet2.jsp must display output of servlet1. It display it, but it doesn/t display addition information from servlet2. And I get this error in Log file:

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

As I understant this error appears because when servlet2.jsp call "/servlet1" servlet1 sent response to client and servlet2.jsp doesn't have session anymore.

So my question is - How can I fix my code to accomplish what I want? Is it possible to include output of some servlet to some jsp file? If it's possible, is it a good or bad practice?

1
Is it really necessary to have two seperate servlets, each just forwarding to a single JSP page? Couldn't you use just one servlet and route the request to the JSP pages as required?ewanc
This is really strange design which indicates a fundamental misunderstanding somewhere. Perhaps your servlets are simply doing "too much" that shared code needs to be refactored into a standalone Java class which can in turn be imported/used by both servlets? Ultimately, just invoke only one servlet which in turn forwards to the desired JSP instead of the other way round. See also a.o. stackoverflow.com/q/5649722BalusC

1 Answers

3
votes

In servlet2.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<jsp:include page="/servlet1" />

In servlet2.jsp, you have used jsp:include. It is including the response of the servlet1 response.

But the servlet1, it is going to forward the response to another jsp. So that exception occurs.

To avoid this, in Servlet1 class should use view.include(request,response); instead of 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);
    }                                                                               
}