I have the following processor.jsp file:
<%
response.sendRedirect("http://buzz.example.com");
%>
I want to change it so that it inspects the HTTP request URL for the presence of the word "fizz" and, if it exists, redirect the user to http://fizz.example.org instead.
So something like:
<%
String reqUrl = request.getURL().toLowerCase();
String token = null;
if(reqUrl.contains("fizz")) {
token = "fizz";
} else {
token = "buzz";
}
String respUrl = "http://%%%TOKEN%%%.example.com".replace("%%%TOKEN%%%", token);
response.sendRedirect(respUrl);
%>
However this doesn't work. Any ideas on what I should be using instead of request, or if I'm doing anything else wrong?
Always try to avoid Scriplet instead use JavaServer Pages Standard Tag Library and Expression Language that is more easy to use and less error prone.
Sample code using JSTL <c:choose> that is equivalent to Java switch case.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
...
<c:set var="defaultURL" value="xyz"/>
<c:choose>
<c:when test="${fn:containsIgnoreCase(request.getRequestURI(), 'fizz')}">
<c:redirect url="http://fizz.example.com" />
</c:when>
<c:when test="${fn:containsIgnoreCase(request.getRequestURI(), 'buzz')}">
<c:redirect url="http://buzz.example.com" />
</c:when>
<c:otherwise>
<c:redirect url="http://${defaultURL}.example.com" />
</c:otherwise>
</c:choose>
Read more about All Tags | Functions and Oracle Tutorial - Using JSTL
Related
I want add function return type of access in my session , its work with this code but i want use jstl in jsp , can you offer any idea ?
<%
if (String.valueOf(session.getAttribute("acces")).equalsIgnoreCase("admin")) {
%>
<li class="page_item">Admin</li>
<%
} else {
%>
<%
}
%>
Use JSTL core taglib
<c:set var="cond" value='${"admin".equalsIgnoreCase(sessionScope.acces)}'/>
<c:if test="${cond}">
<li class="page_item">Admin</li>
</c:if>
<c:if test="${!cond}">
</c:if>
my jsp page has:
<%# page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
...
<c:set var="currentUser">
<sec:authentication property = "principal.username"/>
</c:set>
<c:if test = "${currentUser eq user.login}" >
...
when i compare English words evaluation returns true, but when it comes to Russian language, etc - false.
At start i thought that this can be trouble with jsp encoding but when i run something like that
<c:if test = "${'Андрей' eq 'Андрей'}" >
it comes true
even
<c:if test = "${currentUser eq 'Андрей'}" > turns `false`
At the end i want to add that browser displays values ${currentUser} and ${user.login} as the same
${currentUser}<br>
${user.login}
comes
Андрей
Андрей
Thanks in advance for your reply!
Please try this test page. It works for me.
<%# page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%
pageContext.setAttribute( "currentUser", "Андрей");
%>
Test page.
<c:if test = "${currentUser eq 'Андрей'}" >
Yes, they are equal.
</c:if>
<c:if test = "${currentUser eq currentUser}" >
Yes, they are equal. currentUesr is ${currentUser}
</c:if>
Output:
Test page. Yes, they are equal. Yes, they are equal. currentUesr is Андрей
I'm working on a legacy Tomcat server that is no longer supported by the software developer that provided it. web.xml doesn't tell me what version of JSP I'm working with, but all the .class files are Java 1.5.
I have a customer who is upset, because the system has html boxes that are auto-populated by Java, and it fills it straight the the (unordered) results of an XML database query. I'm trying to sneak a bit of code into the JSP for the Selector to sort the list of fields before they are populated, but it doesn't work and I don't understand why.
The (abridged) relevant code:
<%# page import="src.explorer.ObjectStateFactory"%>
<%# page language="java" %>
<%# taglib uri="/WEB-INF/c.tld" prefix="c" %>
<jsp:useBean id="ExplorerViewContext" scope="session" type="src.explorer.ExplorerViewContext"/>
...
<c:forEach var="nc" items="${ExplorerViewContext.networkControllers}">
<c:choose>
<c:when test="${nc.name == ExplorerViewContext.networkControllerSelection.name}">
<option value="<c:out value="${selectAction}${nc.objectKey}"/>" selected><c:out value="${nc.name}"/></option>
</c:when>
<c:otherwise>
<option value="<c:out value="${selectAction}${nc.objectKey}"/>"><c:out value="${nc.name}"/></option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
The relevant code with my additions:
<%# page import="src.explorer.ObjectStateFactory"%>
<%# page import="java.util.*"%>
<%# page language="java" %>
<%# taglib uri="/WEB-INF/c.tld" prefix="c" %>
<jsp:useBean id="ExplorerViewContext" scope="session" type="src.explorer.ExplorerViewContext"/>
...
<%
final Comparator<src.explorer.XmldbObjectState> NC_ORDER = new Comparator<src.explorer.XmldbObjectState>(){
public int compare(src.explorer.XmldbObjectState nc1, src.explorer.XmldbObjectState nc2){
return nc1.getName().compareTo(nc2.getName());
}
};
List myList = ExplorerViewContext.getNetworkControllers();
java.util.Collections.sort(myList,NC_ORDER);
%>
<c:forEach var="nc" items="${myList}">
<c:choose>
<c:when test="${nc.name == ExplorerViewContext.networkControllerSelection.name}">
<option value="<c:out value="${selectAction}${nc.objectKey}"/>" selected><c:out value="${nc.name}"/></option>
</c:when>
<c:otherwise>
<option value="<c:out value="${selectAction}${nc.objectKey}"/>"><c:out value="${nc.name}"/></option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
Basically, I'm trying to grab the list and sort it before it gets sent to the HTML. The problem is, myList always comes up empty, and I don't understand why. I'm guessing that ExplorerViewContext.networkControllers in the original code is calling the getNetwrokControllers() method on an instance of ExplorerViewContext, yes? Why can't I do the same thing in a scriptlet and reformat the output a little before serving it?
You should not add scriptlet code to code that is already using JSTL only. The better thing to do would be to edit the bean class src.explorer.ExplorerViewContext to sort the insides for you automatically.
In any case, the reason ${myList} does nothing in the JSTL is that variables created in scriptlets (i.e. between <% and %>) do not exist for JSTL. To get a variable to exist in JSTL you have to create it in JSTL, or set it in the page context, or it has to be in the session or the request. Generally you put it in the session or request in a servlet.
In this case, your list is in the bean, so it would be better to just edit the bean class to sort the list. But you could set the variable into the page context here so that JSTL can use it:
<%
...
List myList = ExplorerViewContext.getNetworkControllers();
java.util.Collections.sort(myList,NC_ORDER);
pageContext.setAttribute("myList", myList); //set in pageContext so JSTL can see it
%>
<c:forEach var="nc" items="${myList}">
As far as the code being "legacy" adding scriptlets to it would make it even more legacy. The fact is, this code is more modern than the modifications you were trying to add. But only slightly so, since using <jsp:useBean> is an obsolete way of using beans.
I'm creating a JSP .tag file that will handle this use case:
<my:safeParam paramName="param1" defaultValue="testvalue"/>
Where the behavior will be to take a request parameter, escape its value for "safe" usage, and place that escaped value back on some scope (e.g. request) under the same name as the parameter (although it could be another name).
I have an implementation that works, but I've got scriptlet in there because I couldn't find a way to use variable variable names in just JSTL. But I'm no JSTL wizard, so I thought I'd see if there's a syntax/approach I'm missing. Here's the working safeParam.tag file:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%# attribute name="paramName" required="true" %>
<%# attribute name="defaultValue" %>
<%
String name = (String) pageContext.getAttribute("paramName");
%>
<c:if test="${not empty defaultValue}">
<%
request.setAttribute(name, pageContext.getAttribute("defaultValue"));
%>
</c:if>
<c:if test="${not empty param[paramName]}">
<c:set var="escaped" value="${fn:escapeXml(param[paramName])}"/>
<%
request.setAttribute(name, pageContext.getAttribute("escaped"));
%>
</c:if>
(I sure wish EL was escaped automatically.)
<c:if test="${empty paramName}">
${defaultValue}
</c:if>
<c:if test="${not empty paramName}">
<c:out value="${paramName}" escapeXml="true"/>
</c:if>
I probably won't use this approach because it reduces the conciseness I was seeking with this custom tag, but just to document it as an option... (I'm not sure if this is what Frank Yeung is getting at.)
I could make the tag simply output the default-or-escaped parameter value, then make the user of the tag wrap that in a <c:set>.
Tag:
<c:choose>
<c:when test="${empty param[paramName]}">
${defaultValue}
</c:when>
<c:otherwise>
<c:out value="${param[paramName]}"/>
</c:otherwise>
</c:choose>
JSP:
<c:set var="myVariable">
<my:safeParam paramName="folder" defaultValue="homeFolder"/>
</c:set>
But really my goal has been to do everything inside the tag.
I need to check the browser's user-agent to see if it is IE6. However I shouldn't use scriptlets (we have a strict no scriptlets policy) to do this.
Currently I use
<%
String ua = request.getHeader( "User-Agent" );
boolean isMSIE = ( ua != null && ua.indexOf( "MSIE" ) != -1 );
%>
<% if( isMSIE ){ %>
<div>
<% } %>
What is the cleanest way to do this using JSTL, EL, etc and not scriptlets?
<c:set var="browser" value="${header['User-Agent']}" scope="session"/>
<c:if test="${fn:contains(header['User-Agent'],'MSIE')}"></c:if>
If you are using spring-mobile framework you can use following to check device type
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:choose>
<c:when test="${currentDevice.normal}"><p>"Welcome desktop user"</p> </c:when>
<c:when test="${currentDevice.mobile}"><p>"Welcome mobile user"</p> </c:when>
<c:when test="${currentDevice.tab}"><p>"Welcome tab user"</p> </c:when>
</c:choose>