0

Does anyone know how to check if a jsp already includes another jsp twice?

mainJSP.jsp[
   include myJSP.jsp[

       <jsp:include page="foo.jsp"/>
    ]
    include myJSP1.jsp[

       <jsp:include page="foo.jsp"/>//This should never happend
    ]
 ]

Any ideas?.

paul
  • 12,873
  • 23
  • 91
  • 153
  • as in hardcoded? before you write it, check whether it's already there. Since there is no syntactical error in there, I doubt there is a tool that checks this. – Stultuske Mar 27 '15 at 08:31
  • Can you put a flag in included foo.jsp and check if it already exists in pageScope? (if you are using jstl). – drgPP Mar 27 '15 at 08:32
  • @drgPP I´m using jstl, can you paste me a code example please? – paul Mar 27 '15 at 08:40
  • @paul, i'm a little bit confused, do you want to CHECK if it is included twice, or rather to NOT include it one more time if Foo.jsp was already included in main page? – drgPP Mar 27 '15 at 09:15
  • not included if was already included – paul Mar 27 '15 at 09:17

2 Answers2

2

After some time of playing, i was able to get the result you wanted, but i was able to resolve it only using scriplets. Suppose that:

Your Foo.jsp is: (Page which will be included in myJsp1 and myJsp2)

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.util.HashSet" %>

<%String hasInclude = "itHas";
request.setAttribute("hasInclude", hasInclude); %>
<%HashSet<String> hasIncludes = new HashSet<String>(); 
request.setAttribute("hasIncludes", hasIncludes);%>
<h2>Inside include</h2>

Your myJsp1:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.HashSet" %>
<h1>Inside jsp1</h1>
<%
String hasInclude = (String)request.getAttribute("hasInclude");
HashSet<String> hasIncludes = (HashSet<String>)request.getAttribute("hasIncludes"); %>
<%if (hasIncludes==null||!hasIncludes.contains(hasInclude)) { %>
<jsp:include page="include.jsp" />
<%if (hasIncludes==null) {
hasIncludes = new HashSet<String>();
hasIncludes.add((String)request.getSession().getAttribute("hasInclude"));
} else {
    hasIncludes.add(hasInclude);
}
request.setAttribute("hasIncludes", hasIncludes);%>
<%}%>

Your myJsp2: (same code as myJsp1 before include)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.HashSet" %>
<h1>Inside jsp2</h1>
<%
String hasInclude = (String)request.getAttribute("hasInclude");
HashSet<String> hasIncludes = (HashSet<String>)request.getAttribute("hasIncludes"); %>
<%if (hasIncludes==null||!hasIncludes.contains(hasInclude)) { %>
<jsp:include page="include.jsp" />
<%if (hasIncludes==null) {
hasIncludes = new HashSet<String>();
hasIncludes.add((String)request.getSession().getAttribute("hasInclude"));
} else {
    hasIncludes.add(hasInclude);
}
request.setAttribute("hasIncludes", hasIncludes);%>

<%}%>

And finally the main.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:include page="myJsp1.jsp" />
<jsp:include page="myJsp2.jsp" />

</body>
</html>

The output of main will be:

Inside jsp1

Inside include

Inside jsp2

drgPP
  • 926
  • 2
  • 7
  • 22
  • Actually you should check if isFoo is null, that means that page was not included. – drgPP Mar 27 '15 at 09:00
  • Sorry this wont works, I explain a little bit better what I want – paul Mar 27 '15 at 09:01
  • I read that implementation here on stackOverflow, but I dont like it – paul Mar 27 '15 at 09:22
  • And The idea is that myJSP and myJSP1 dont have to know each other and mainJSP, has to be an isolated jsp – paul Mar 27 '15 at 09:23
  • @paul, from your diagram, i understand it like, you are including two different jsp pages, which inside has the same (Foo.jsp) include, so the idea is to check if the included myJsp has an include of Foo.jsp and the included myJsp1 also has an include of Foo.jsp then do not include myJsp1, is it correct? Or rather to include myJsp1 but not include the Foo.jsp inside it? If it is like this, than this is a kind of includeception :) – drgPP Mar 27 '15 at 09:30
  • in case that foo has been included in myJsp I still want include myJsp1 but without include foo again. – paul Mar 27 '15 at 09:36
  • what do you mean with includeception? – paul Mar 27 '15 at 09:37
  • @paul, check the new edit, besides i wasn't able to do all this decision with jstl, but you know, you must use scriplets where you can't use jstl to get desired functionality. – drgPP Mar 27 '15 at 12:12
  • Thanks but I did not want use scriptlets!. it will introduce too much complexity. I thinking just keep in simple and add foo.jsp in the main.jsp. Problem is if the developer forget to add it there myJSP and myJSP1 wont work properly after being render – paul Mar 27 '15 at 12:21
1

A jsp file generates a regular java method that adds text to the output stream so you can return early. See How to stop processing a JSP early?.

Try the following in any file that you don't want included twice.

foo.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.HashSet" %>
<%
// Just be careful that the attribute name is unique to this file
if (!request.getAttribute("foo.jsp") == null) {
   return;
}
request.setAttribute("foo.jsp", true)
%>
<h1>Contents of the file</h1>
...

To minimize the problem of having multiple includes with the same attribute name, you can use something like the following to generate a unique attribute name in every jsp. See Get current filename in JSP

String __jspName = this.getClass().getSimpleName().replaceAll("_", ".")

This technique is kind of similar to the popular C approach to prevent double inclusion

#ifndef FILE_NAME
#define FILE_NAME
... file contents
#endif
Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217