Unable to access common content in servlet to jsp call - java

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.

Related

Is it possible to create a local page scope in a JSP?

I'm working on a componentization system based on JSPs. This means that parts of the JSP can be moved from one JSP to an other one via drag and drop and leads to a need for a local page scope as variable of a component defined in one JSP my collide in an other JSP.
I can use Servlet 3.0 / JSP 2.2 / JSTL 1.2.
++ Tag File ++
The straight way of doing that would be to create a tag file for a component or something similar as they have this local page scope. But for every change in the tag file it would need to get redeployed and needing to create a tag file needs some time by itself. But if there is no other solution this direction (custom tags, tag files, JSP includes,...) is probably the way to go.
++ Namespace prefixing/suffixing ++
In Portlets one is supposed to concatenate each variable with a namespace provided from the portlet response object. I could do something similar but this can lead to side effects and unexpected behavior. If someone forgets to prefix/suffix the namespace it might work for some time but stops working at an other time without changing the code when the component moved to an other JSP with a conflicting variable name.
++ Custom Tag wrapping ++
I was hoping that I as a component framework developer can wrap the component code of a component developer with a tag file for a component tag like this
<a:component>
<div data-component-id="9">
<c:set var="componentId" value="9"/>
<c:set var="path" value='${abc:getCurrentPath()}_${componentId}'/>
<c:set var="resource" value='${abc:getResourceFromPath(path)}'/>
<c:set var="val" value="${resource.getValue('paragraphValue')"/>
<p><c:out value="${value}"/></p>
</div>
</a:component>
to have the variable in the local page context of the tag file. But instead they are in the context of the surrounding page. I'm looking for something like this
<% { %>
<div data-component-id="9">
<%
String componentId = 9;
String path = obj.getCurrentPath()+componentId;
Resource resource = otherObj.getResourceFromPath(path);
String value = resource.getValue("paragraphValue");
%>
<p><c:out value="<%=value%>"/></p>
</div>
<% } %>
which would create a code block in which variables have their own namespace. But of course for JSTL and JSTL-EL instead of scriptlet code.
I had a look at the JSTL specification but did not find out if there is a way to create such a local page scope. But I didn't check everything as it's huge and I'm not sure if it's possible with custom tags.
It is clear to me that bigger code blocks should not be in the JSP but with the framework I would like to provide simple solutions for smaller components.
++ Changing the JSP code ++
When components are initially placed on a JSP or moved around via drag 'n drop I actually move the JSP code of a component from one JSP to an other or within a JSP. This means I can also programmatically manipulate the JSP code of a component if it doesn't get too complex and it helps solving the problem.
As I thought that custom tag wrapping could be the ideal solution I created an other more specific question and I've got an answer here that solves the problem.
It's simply to remove all pageContext attributes before the evaluation of the body and adding them again at doEndTag().

Pass JSP variable to a java class method

I have a JSP file named as project.jsp. It contains a variable
String context = request.getcontextpath();
which will deliver context path of my server URL.
/ARUBA-LIB-G3245-KITKAT from http://localhost:8080/ARUBA-LIB-G3245-KITKAT/.
Now I want to access this context variable from my project.jsp file to java class which is in jar format file and resides in WEB-INF/lib/AuthenticateDetails.jar.
How can I access this variable from specified java class file?
The same as in java, an import statement and so on.
<%# page import="java.util.Random"
import="org.authdetails.dao.SomeClass" %>
(Or many imports in one import=... with line break in string.
<% new SomeClass(contextPath); %>
Using the MVC (Model-View-Controller) principle, one normally has a servlet (Controller, compilable!) that prepares the data (Model) and puts the data as request attributes, and then forwards to the JSP (view).
In the JSP you can use EL (Expression Language) variables, where some are predefined to access session variables, request parameters and such.
Combining that with JSP tags, one rarely needs to use <% ... %> scriptlets.
Pass the context path variable to the processing method in the library class (library class should be accessible from the jsp though import directive)

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.

Dynamically include HTML in JSP

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>" />**

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