Dynamically include HTML in JSP - java

I want to include html pages dynamically in a JSP page. I'm fetching the html url from HTML forder and using struts2 to pass the value to JSP page but I'm unable to do this on JSP using either jsp:include or #include tags.
For Example,
I have variable html Url like /somepath/variablehtmlname.html in my struts action property. I want to use this path to include the actual html files located at /somepath location.

<%# include ... %> is evaluated when your JSP pages are compiled and have no access to request variables (like Struts 2 action properties.) Use <c:import /> or <s:include /> instead, which include content on a per-request basis. <jsp:include /> should also work, but (as #BalusC requested) without the code, we can't tell why it doesn't.
Reusing Content in JSP Pages

I agree with the first answer (BobG). You can also simply have the JSP page directly serve up an http forwardTo using the refresh tag, where the servlet writes the new url location to a session variable : <meta http-equiv="refresh" content="0; URL=<%=htmlSessionLink>" />**

Related

Problems with sendRedirect() function

I have this strange problem with sendRedirect function which i can't explain.
I have a header page as Header.jsp as :
<%# page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*,java.util.*" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Online Exam Portal</title>
<style type="text/css">
body{
background-color : lightgreen;
}
</style>
</head>
<body>
<%
if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");
}
%>
<img src="exam_header01.jpg"/>
<br />
Welcome <%=session.getAttribute("userid")+"This is Working"%>
Change Password
Logout
<hr/>
i have included this header page in all the pages, i did this since i wanted to prevent the users who don't have valid session and redirect to signup page but it doesn't redirects
instead it shows Welcome null and also :
1> If i write anything inside that if statement it works fine! , like :
if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");//this is not executed
out.println("This Runs");//this String is printed
}
2> If i write the same code inside the main page(i.e after header page) it works fine!
3> And most importantly the code works when i replace it by :
<jsp:forward page="signup.html"/>
What could be the problem here. it would be really appreciated if anyone can explain with examples.
Update :-
Even If i print to my page after Redirect it will work if i use if statement use after including the Header :
<jsp:include page="Header.jsp"/>
<%if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");
out.println("I cant See this because page is redirected ");
}
%>
</body>
</html>
As others have said, this isn't the best way to achieve what you want to achieve.
That said, the problem you are seeing is as a result of using the wrong type of include. You are using request time include (<jsp:include page="..." />) which processes the included page and inserts the output (if any) into the current page. If you call response.sendRedirect() from an included page it is ignored. Hence your current solution doesn't work.
You would need to use a translation time include (<%# include file=... %>) which takes the source of the included page, inserts it into the source of the current page and then processed the current page as if it was a single JSP.
From the javadoc:
After using this method, the response should be considered to be committed and should not be written to.
You don't respect this, since you continue to print to the response after sendRedirect().
The main problem is in your architecture. JSPs are view components. They should not contain scriptlets, and should not redirect. They should only generate HTML markup from beans stored in request attributes by a controller, written in Java, as a servlet or action of your preferred MVC framework. And to generate this markup, they should only use the JSP EL, the JSTL and other custom tags.
Instead of repeating the login check in every JSP, which is extremely error-prone and repetitive, you should have a servlet filter which intercepts all the requests, makes the check, and let the next component (a controller) do its job of the user is authenticated.
request --> authentication filter --- if authenticated ---> controller --- forward to ---> JSP
|
|--- if not authenticated --- redirect to --> authentication controller --- forward to ---> login.jsp
For authentication purposes, use Filters.
A Filter is nothing but a Java class that is used to preprocess the request before it is forwarded to the resource the user asked for.
Eg. if you have mapped your filter class with a servlet, then as and when the request comes in for this servlet, it is initially intercepted by the filter class(which contains your authentication code) and if it succeeds in authentication then only the request is forwarded to the servlet. This makes the authentication more easy and flexible.
For this, you need to map your filter class with the servlet inside web.xml.
In short, response.sendRedirect() would not serve your purpose and you have to ultimately rely on filters.

Editing the jsp content from a taglib

I have a filter that processes a given servlet mapping and includes a JSP that holds the structure of every page.
servletContext.getRequestDispatcher( "/index.jsp" ).include( request, response );
Inside the jsp I have a custom jstl tag that handles the inclusion of another JSP portion inside the parent according to a series of rules (the inclusion is done inside the "body" tag:
pageContext.include( ProcessURI.getJSPLocation( request.getRequestURI() ) );
Inside to the latest included JSP I want to be able to write a stylesheet and append to the response. I am using a taglib for that.
<taglib:head>
<link rel="stylesheet" href="some.css" >
</taglib:head>
Since the contents of the last JSP is included into the "body" tag I need to access the "head" and insert the HTML after the last item (I cannot insert the stylesheet inside the "body" tag).
<head>
...
<!-- I want to insert here -->
<link rel="stylesheet" href="some.css" >
<head>
<body>
...
How would I access the processed response inside the last taglib (taglib:head) where I can edit and insert its body content into the first included jsp (/index.jsp)?
I suppose it is possible to access the response that has been processed until the given taglib call, am I correct?
I accept different ways of achieving the same result using other techniques than mentioned above.
I have solved creating one taglib to load the file page.jsp and another one for page-head.jsp. In that way I process the data in the proper order without doing some crazy response manipulation.

Unable to access common content in servlet to jsp call

i have scenario where, i need to call a jsp from a servlet and pass a hashmap containing custom objects whose details jsp needs to display...(this is working fine using Request Dispatcher and jstl in jsp code)
however my jsp includes some other jsps that define the look and feel of the whole application.
my structure is as:
TestProject
<Tabs>- images
<Tabs><Tabs>* background.jpg
<Tabs>- jsp
<Tabs><Tabs> * common
<Tabs><Tabs><Tabs>+ common.jsp
<Tabs><Tabs> * xml
<Tabs><Tabs><Tabs> + XMLDisplay.jsp
my XMLDisplay.jsp includes common.jsp which in turn has path for background.
the common.jsp is common to all other files in application and is working fine.... but not in XMLDisplay.jsp.
i have displayed the context path and the servlet path in XMLDisplay.jsp and its fine. (same as in other files) however for images the path somehow is getting distorted.
and the images are getting accessed from
http:localhost:8080\images\background.jpg
instead of
http:localhost:8080\TestProject\images\background.jpg
the only difference in the other pages is that the call is from one jsp to another while here the call is from servlet to jsp.
Try to use jstl tag <c:url value="\images\background.jpg" var="image1"/> from taglib
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
You should prefer this tag for resources like (*.js, images, etc.) and for constructing links with parameters.

performance difference between <c:import url="child.jsp" /> and <jsp:include ...>

I know the performance difference between the following two
Include directive (<%# include file="test.jsp" %>): This includes the contents of the file during the compilation phase—i.e., when the page is converted to a servlet.
Include action (<jsp:include page="test.jsp" flush="true" />): This includes the contents of the file in the run-time—i.e., when a request is made for the page by the user.
But what about JSTL tag <c:import url="child.jsp" />
is the content included during the compilation phase or run-time?
Thanks!
It is included at runtime. And you can put an absolute URL there (you can include html from 3rd party sites)
If you're talking about the <jsp:include /> tag it include a jsp a runtime. In this way you can use it recursively.
About the c:include...is a tag so (I think) it's a runtime phase...
By default with c:import, the content of an imported resource is included inline into the JSP page at runtime. Although, it is also possible to access the resource a String object or a Reader object.
The URL could be absolute (any outside web app) or relative (to the context)
HTH

How can I reuse code in JSP?

For example, a user will be rendered throughout my application as
<div class="user">
<p class="username">${user.name}</p>
<p class="karma">${user.karma}</p>
<img src="/users/${user.id}"/>
</div>
How can I reuse this code block?
Note - my code is running within a tag, so I can't use tags for this (or any JSP) otherwise I get a Scripting elements are disallowed here error.
Edit
I'm trying to use a tag file, but getting PropertyNotFoundException.
This is my tag file called 'user.tag':
<%#tag description="User" pageEncoding="UTF-8" %>
<a href="../user/showUser.do?userId=${user.id}">
<p>${user.name}</p>
<img class='avatar' src='${user.avatarUrl}' alt=""/>
</a>
And usage inside a jsp:
Where job.poster is a java bean with id, name, and avatarUrl properties.
If I add
<%#attribute name="user" %>
to the tag file, then I get an exception
Property 'id' not found on type java.lang.String
Since JSP 2.0, there is yet another kind of tags: Tag files. Tag files are JSP custom tags written as a JSP template itself, which seems to be what you want.
http://fforw.de/post/creating-jsp-layouts-with-page-tags/ shows how to use such a tag file as general layout solution. Using them as component should be even easier.
You should be able to use tag files within tag files; this works for me in a JSP 2.2 container:
<%-- mytag.tag --%>
<%#tag description="demo code" pageEncoding="UTF-8"%>
<%#taglib prefix="cust" tagdir="/WEB-INF/tags" %>
<%#attribute name="message"%>
<cust:mytag2 message="${message}" /><%-- uses mytag2.tag --%>
If that fails, you can use the include directive: <%#include file="/WEB-INF/jspf/fragment.jspf" %>
Note that the spec says about tags:
Directive Available? Interpretation/Restrictions
======================================================================
page no A tag file is not a page. The tag directive must
be used instead. If this directive is used in a
tag file, a translation error must result.
So, fragment.jspf must not have a any elements that are not supported in tags, including a page directive.
For the example you have given it sounds like some templating framework is needed, to display the user badge on each screen. At its simplest level this may just be a jsp:include which always includes your "UserBadge.jsp".
If you are running on a web framework e.g. JSF you may use Facelet templates or write a custom component for this. So the answer depends on what framework you have. Breaking it down to just JSP and JSTL - the included JSP or a javax.servlet.jsp.tagext.Tag would certainly reduce the duplication.
Always be careful to follow the DRY Principle... Don't Repeat Yourself!
I feel sometimes creating a .tag file is overkill (especially if it's only for one page), and I've wanted what you describe for years, so I wrote my own, simple solution. See here:
https://stackoverflow.com/a/25575120/1607642
Why don't you use a custom tag or jsp functions.
Thanks,

Categories