Right way to write a JSTL expression plus a string - java

Hy guys, I apologize if this is a stupid question, but I couldn't find any examples on how to do this.
My expression is currently ${fn:substringBefore(var1, \"#\")}#domain.com.
I've been trying multiple ways of adding the '#domain' string at the end, but none of them seem to work.
Could you let me know if this is at least possible?

Disclaimer: I've never used JSTL, but I've learned a lot of technologies, most of them alone, by just reading the materials available online. So this answer is more about the thought process involved in solving these when I'm stuck.
When learning new technologies it's usually best to start at the documentation and examples. In this case just by searching for jstl fn:substringBefore I've found this page where fn-substringbefore section has the following example:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="string" value="Hi, This is JAVATPOINT.COM developed by SONOO JAISWAL."/>
${fn:substringBefore(string, "developed")}
</body>
</html>
So it seems like this function should be used by referencing a string (found in the previous line of the example) that will be split at the second argument, returning the first part of the split.
Also the "-s are not escaped in the example, so I would try something like.
${fn:substringBefore(referenceToFullEmailAddress, "#")}
All this is assuming that what you were trying to achieve was to retrieve the first part of the email address, before the #domain.com part.
This is also a reason why it's always a good practice to include more context in your questions.

Related

DOUBLE_WHITESPACE in PATH error

i am learning JSTL and from tutorials point in this link
when i tried to execute that example in the page which is
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title><c:url> Tag Example</title>
</head>
<body>
TEST
</body>
</html>
i am getting following error.
but i could not understand why and what is the solution for that?
The validator is probably confused by the nested double quotes:
TEST
You can make the code cleaner by doing:
<c:url value="/jsp/index.htm" var="myUrl" />
TEST
which assigns the value of the processed URL to a var named 'myUrl' and then uses JSP Expression language to output the URL.
Change this line:
<title><c:url> Tag Example</title>
By:
<title>&LT;c:url&GT; Tag Example</title>
Otherwise, the JSP engine will interpret this (<c:url>) as the beginning of a tag to be processed.
You need to escape your nested quotes as
TEST
Otherwise the HTML parser perceives "<c:url value=" as the href value and complains about the space in between. Alternatively, you can make use of single and double quotes as
<a href='<c:url value="/jsp/index.htm"/>'>TEST</a>
Or,
TEST

jsp command <%=%> being ignored when it is used in a Javascript statement, inside a taglib tag statement?

An example will make this clearer!
The jsp file...
<%# taglib prefix ="jam" uri= "http://jam.tld" %>
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%>
<%
String targetPage = true ? "toast" : "bread";
%>
<jam:text onmousedown="movePage('<%=targetPage%>');" id="<%=targetPage%>"><%=targetPage%></jam:text>
Note - the taglib is not mine and I have no control over it. (it isn't really called jam either :).
This then creates this HTML...
<td onmousedown="movePage('<%=targetpage%>;');" id="toast">toast</td>
Which as you can see: the <%=targetPage%> was only replaced/parsed in the non-javascript bit?
The compiled jsp file looks like this:
jspx_th_jam_005ftext_005f2.setOnmousedown("movepage('<%=targetpage%>')");
Anyone know what is going on, or how to fix it?
Why is the <%=%> tag being ignored when it is part of JavaScript statement?
:)
Here's a bit of a cheat solution, you dont need the JSP tag in that JS call. In fact, it's tidier this way
<jam:text onmousedown="movePage(this.id);" id="<%=targetPage%>"><%=targetPage%></jam:text>

Struts 2, multiple views and jQuery - How do I reuse common code?

I've read most of the online resources for building a simple "Hello World" app using Java and Struts 2. I understand the simple stuff. My problem is that I'm trying to expand that learning and build a large scale app, and I just don't see how to connect the dots.
Scenario:
I've got three views to begin with: Home.jsp, MyAccount.jsp, Contact.jsp. Each has the following HTML:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/common.js"></script>
...
</head>
<body>
<!-- If logged in, says "hello <s:property name="username">"
Else displays link to .show() #loginPane -->
<div id="accountHeader">...</div>
<!-- Displays <s:textfield> tags and <s:submit> tag to accept username and password -->
<div id="loginPane" style="display: none">...</div>
<header>...</header>
<nav>...</nav>
<!-- Displays view-specific content that includes Struts 2 tags -->
<div id="content">...</div>
<footer>...</footer>
</body>
</html>
So, obviously there is a lot of code common to each view (anything not in #content div).
How do I architect these views for code reuse?
What I've tried:
Placing common code in common.js and using jQuery .html() calls to populate <div>s. [Doesn't work because jQuery cannot generate code with <s:> tags.]
Using only one .jsp view file and placing view-specific code in common.js to be generated with jQuery .html() calls. [Doesn't work for the same reason -- jQuery cannot generate code with <s:> tags.]
Placing all view components in .jspf files and loading each with jQuery .load() calls from common.js. [Doesn't work -- I'm guessing the .jspf files need the Struts 2 <%taglib ...%> included in each, but jQuery .load() treats the <%taglib ...%> as text to be displayed in the <div>... and also fails to properly generate the <s:> tags.]
What is the proper way to do this? How do I architect my view(s) for code reuse?
My apologies if this isn't the proper forum to ask for architecture help, but I'm really struggling here... Perhaps point me to a more appropriate forum or an online tutorial that addresses this type of architecture?
Thanks in advance!
I've used several methods to accomplish this type of re-use of code including Tiles and tooling around with Sitemesh and other template frameworks. What I've found is that, much as Steven Benitez, in the end I preferred to use JSP taglibs, native Struts2 taglibs, and JSTL to essentially build out my own templating routines. The main reason I prefer this is that there tends to be less overhead and it's been a lot easier to maintain and extend in the long run.
Generally What I do is define my base template, index.jsp for example, and then in each independent Struts controller class I will define what page fragment is used. I try to split my controllers up in such a way that each page or function is handled by a single controller and I implement the Preparable interface. This way I can set a parameter for the page to reference. Sometimes I set it as a variable in the controller class, sometimes a sessions variable depending on what type of stating I need for the application.
Once I have a variable with the page to reference, I can just use a JSTL import or Struts include tag to load the page fragment.
The controller class would look something like this:
#Results({
#Result(name = "success", location = "/WEB-INF/content/index.jsp")
})
public class IndexController extends RestActionSupport implements Preparable{
private String page;
private String pageTitle;
#Override
public void prepare() throws Exception {
page = "home";
pageTitle= "My Home Page";
}
...
}
And then the JSP would look something like this:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title> ${pageTitle}</title>
</head>
<body>
<c:import url="${page}.jsp" />
</body>
</html>
EDIT: Fragment page example:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="s" uri="/struts-tags"%>
<div>
<h1>Welcome Home!</h1>
</div>
<script type='text/javascript'>
$(document).ready(function() {
// page specific scripting if needed
);
</script>
You can encapsulate common template code in JSP tag files, as explained in this answer or you can also use decorator frameworks such as Tiles or SiteMesh to do this.
Personally, I prefer JSP tag files. Do not attempt to write out HTML with jQuery or to put all of your code into a single JSP.

JSP, can it work similar to yield, layout, content_for in Ruby/Rails/Erb

I am trying to figure out how to most effectively reuse JSP code.
I love the way Rails/erb works in that way ... with yield, layout, content_for
Example:
main_layout.erb.html
<html>
<head><%= yield :head %></head>
<body><%= yield %></body>
</html>
use
<% content_for :head do %>
<title>A simple page</title>
<% end %>
<p>Hello, Rails!</p>
in controller
layout "main_layout"
What is the closest I can get to this with JSP (without using extra frameworks)? I know about JSP include but that's not really the same as yield.
Any suggestions?
Thanks
I'm not familiar with what yield and content_for provide, but JSP tag files allow you a more robust way to template pages than JSP includes.
Example:
layout.tag
<%# tag body-content="scriptless" %>
<%# attribute name="pageTitle" required="true" type="java.lang.String" %>
<html>
<head>
<title>${pageTitle}</title>
</head>
<body>
<jsp:doBody/>
</body>
</html>
An individual JSP
<%# taglib prefix="z" tagdir="/WEB-INF/tags" %>
<z:layout pageTitle="A simple page">
<p>Hello, JSP!</p>
</z:layout>
Just place your layout.tag in the /WEB-INF/tags directory. You can use any available prefix you want, I just used "z" for the example.
While you mentioned wanting no frameworks on top of stock jsp, the Layout functionality of the Stripes Framework does pretty much exactly what you're asking for.

How to avoid using scriptlets in my JSP page?

I've been told that the use of scriptlets (<%= ... %>) in my JSP pages isn't such a great idea.
Can someone with a bit more java/jsp experience please give me some pointers as to how to change this code so its more 'best practice', whatever that may be?
This JSP is actually my sitemesh main decorator page. Basically my web design has a tab strip and a submenu, and i wish to somehow highlight the current tab and show the correct submenu by looking at the current request URI.
<%# taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
<%= request.getRequestURI().contains("/events/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/events/Listing.action'>Events</a>
<a
<%= request.getRequestURI().contains("/people/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/people/Listing.action'>People</a>
</div>
<div class="submenu">
<% if(request.getRequestURI().contains("/events/")) { %>
List of Events
|New Event
<% } %>
<% if(request.getRequestURI().contains("/people/")) { %>
List of People
|New Person
<% } %>
</div>
<div class="body">
<decorator:body />
</div>
</body>
</html>
Thanks all
I think it helps more if you see with your own eyes that it can actually be done entirely without scriptlets.
Here's a 1 on 1 rewrite with help of among others JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) core and functions taglib:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
${fn:contains(pageContext.request.requestURI, '/events/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/events/Listing.action">Events</a>
<a
${fn:contains(pageContext.request.requestURI, '/people/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${fn:contains(pageContext.request.requestURI, '/events/')}">
List of Events
|New Event
</c:if>
<c:if test="${fn:contains(pageContext.request.requestURI, '/people/')}">
List of People
|New Person
</c:if>
</div>
Here's a more optimized rewrite, note that I used c:set to "cache" expression results for reuse and that I use HTML <base> tag to avoid putting the context path in every link (just make all relative URL's in your webpage relative to it --without the leading slash!):
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, '/events/')}" />
<c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, '/people/')}" />
<html>
<head>
<title>My Events - <decorator:title /></title>
<base href="${pageContext.request.contextPath}">
<link href="assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a ${isEvents ? 'class="selected"' : ''} href="events/Listing.action">Events</a>
<a ${isPeople ? 'class="selected"' : ''} href="people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${isEvents}">
List of Events|New Event
</c:if>
<c:if test="${isPeople}">
List of People|New Person
</c:if>
</div>
It can actually be optimized more if you collect all those "hardcoded" values like events and people and link texts in a Map in the application scope and use under each the JSTL <c:forEach> to display the tabs.
As to your actual question, you can disable scriptlets (and get runtime errors about using it) by adding the following entry in webapp's web.xml. It may help to spot overseen scriptlets.
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
To learn more about EL, check the Java EE tutorial part II chapter 5. Implicit EL objects, such as ${pageContext} are described here. To learn more about JSTL, check the Java EE tutorial part II chapter 7. Note that JSTL and EL are two separate things. JSTL is a standard taglib and EL just enables to access backend data programmatically. Although it is normally used in taglibs like JSTL, it can also be used standalone in template text.
As an aside, is <%= request.getContextPath() %> an acceptable use of scriptlets that isn't frowned on so much?
This may be an unpopular opinion, but if all you do are simple conditionals and text insertions, I cannot find much fault in the use of scriptlets. (Note the if)
I'd probably use JSTL and the expression language, but mostly because it can be less typing, and IDE support may be better (but a good JSP IDE can also find missing closing brackets and stuff like that).
But fundamentally (as in "keep logic out of templates") I fail to see any difference between
<% if(request.getRequestURI().contains("/events/")) { %>
and
${fn:contains(pageContext.request.requestURI, '/events/')
Scriptlets aren't the worst thing in the world. An important consideration is to think about who is going to be maintaining the code. If its web designers who don't have much Java experience, you are probably better off going with tag libraries. However, if Java developers are doing the maintainance, it may be easier on them to go with scriptlets.
If you end up using a tag library and JSTL, you are expecting the maintainer to also learn the tag library and know JSTL. Some developers will be fine with this as it is a skill they want or already have, but for some developers who only have to deal with JSPs every few months or so, it can be lot less painful to work with clearly written scriptlets written in nice, familiar Java.
This isn't a direct answer to your question (and there are already several good ones, so I won't try to add to it), but you did mention:
Can someone with a bit more java/jsp
experience please give me some
pointers as to how to change this code
so its more 'best practice', whatever
that may be?
In my opinion, best practice, with regards to JSP, is that it should be used strictly as a templating engine, and no more (i.e., no business logic in there). Using JSTL, as many pointed out, definitely helps you get there, but even with JSTL, it's easy to do to much in a JSP.
I personally like to follow the rules laid out in Enforcing Strict Model-View Separation in Templating Engines by the Terence Parr when developing in JSP. The paper mentions the purpose of templating engines (separating model and view), and characteristics of a good templating engine. It takes a good look at JSP and points out ways it's not a good templating engine. Not surprisingly, JSP is basically too powerful and allows developers to do too much. I strongly recommend reading this paper, and it'll help you restrict yourself to the "good" parts of JSP.
If you read only one section in that paper, read chapter 7, which includes the following rules:
the view cannot modify the model either by directly altering model
data objects or by invoking methods on
the model that cause side-effects.
That is, a template can access data
from the model and invoke methods, but
such references must be side-effect
free. This rule arises partially
because data references must be
order-insensitive. See Section 7.1.
the view cannot perform computations upon dependent data
values because the computations may
change in the future and they should
be neatly encapsulated in the model in
any case. For example, the view cannot
compute book sale prices as
“$price*.90”. To be independent of the
model, the view cannot make
assumptions about the meaning of data.
the view cannot compare dependent data values, but can test the
properties of data such as
presence/absence or length of a
multi-valued data value. Tests like
$bloodPressure<120 must be moved to
the model as doctors like to keep
reduc- ing the max systolic pressure
on us. Expressions in the view must be
replaced with a test for presence of a
value simulat- ing a boolean such as
$bloodPressureOk!=null Template output
can be conditional on model data and
com- putations, the conditional just
has to be computed in the model. Even
simple tests that make negative values
red should be computed in the model;
the right level of abstraction is usu-
ally something higher level such as
“department x is losing money.”
the view cannot make data type assumptions. Some type assumptions are
obvious when the view assumes a data
value is a date, for example, but more
subtle type assumptions ap- pear: If a
template assumes $userID is an
integer, the pro- grammer cannot
change this value to be a non-numeric
in the model without breaking the
template. This rule forbids array
indexing such as colorCode[$topic] and
$name[$ID] The view further cannot
call methods with arguments be- cause
(statically or dynamically) there is
an assumed argu- ment type, unless one
could guarantee the model method
merely treated them as objects.
Besides graphics designers are not
programmers; expecting them to invoke
methods and know what to pass is
unrealistic.
data from the model must not contain display or layout information.
The model cannot pass any display
informa- tion to the view disguised as
data values. This includes not passing
the name of a template to apply to
other data values.
Incidentally, Terence has created his own templating engine called String Template which supposedly does a really good job of enforcing these rules. I have no personal experience with it, but would love to check it out on my next project.
You may want to start by using tag libraries. You can use the standard tag library JSTL to do most of the common things that you need scriplets for. There are many other richer tag libraries that are used like in the struts2 framework or from apache.
e.g.
<c:if test="${your condition}">
Your Content
</c:if>
would replace your if statements.
The preferred alternative to scriptlets is the JSTL expression language; here's a good overview. You'll need to add the taglib like so:
<%# taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c' %>
As an example, JSTL provides a bunch of implicit objects that give you the stuff you need; the one you want is pageContext.request.
So you can replace <%request.getRequestURI%> with ${pageContext.request.requestURI}.
You can do conditionals using <c:if> tags.
You'll need to use some web framework. Or at least some convenient taglib. Or a templating enginge like FreeMarker.
Ad frameworks:
If you like JSP way of coding, then I'd suggest Struts 2.
<s:if test="%{false}">
<div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
<div>Will Be Executed</div>
</s:elseif>
<s:else>
<div>Will Not Be Executed</div>
</s:else>
Then there's component-oriented JSF.
If you like OOP and coding everything in Java, try Apache Wicket (my favorite) or Google Web Toolkit.

Categories