jstl bug while comparing strings UTF-8.(Spring Security - principal.username) - java

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 Андрей

Related

Evaluating dynamic EL expressions at runtime in JSP page

I am putting together an application and would like to apply "Custom" EL Expressions to sections on the page when it is rendered. This will help me control what parts are displayed on the page given the status of the page. The problem is that the EL Expressions are not being evaluated and treated only as String values. For example
<c:if test="${form.conditionEL}" >
<input type="submit" value="Close">
</c:if>
The value of the ${field.conditionEL} might evaluate to something like "submission.status eq 'COMPLETE'".
So, is there a way to get that string value to be interpreted within the JSP page ?
Thanks for any help in making this happen. Let me know if I missed providing any pertinent information to help resolve.
Environment: Java 8, Tomcat 9, JSP 3.0, Spring
Regards,
Mike
I would simply add the submission status to the page context which let's you simply do:
<c:if test="${submissionStatus eq 'COMPLETE'}" >
<input type="submit" value="Close">
</c:if>
Check whether EL expressions are ignored in your page tag. I've also faced the same issue and this resolved mine.
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false" %>

Sort select box items in a JSP scriptlet

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.

How to inspect JSP request URL for String

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

Is there a better way to write this JSP custom tag?

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.

Why my included JSP file won't get processed correctly?

I am trying (and learning) to build a java web framework, and in the process of developing its' code generator based on the content of the database. In the view making process, I stumble in a difficulty, which I don't know how to solve it.
Firstly, I want all the pages to be created using the following index.jsp :
<body>
<%# include file="header.jsp" %>
<hr/>
<%# include file="body.jsp" %>
<hr/>
<%# include file="footer.jsp" %>
</body>
And, in the body.jsp, I want it to be like this :
<jsp:include page="${application_modul}" %>
Where application_modul is an attribute defined in its' controller this way :
request.setAttribute("application_modul","user_account\\view_user_account.jsp");
It can find the file correctly, but the processed jsp is not what I expected. Here :
<c:forEach items="[application.models.UserAccountModel#18a49e0, application.models.UserAccountModel#1f82982]" var="item" varStatus="status" >
<tr>
....
You can see the items attribute of jstl forEach, got its variable name (toString())...
Any Idea what the problem is????
I hope I describe my problem correctly
Many thanks!
PS :
I already create a quick fix for this, but not what I want it though. In the generated view_user_account.jsp, I do it like this :
<body>
<%# include file="header.jsp" %>
<hr/>
<c:forEach items="${row}" var="item" varStatus="status" >
<tr>
....
<hr/>
<%# include file="footer.jsp" %>
</body>
You can see that I create the whole file here...
EDITED:
PS : ${row} is an ArrayList populated with data from certain table
So, to summarize your problem in a single sentence, JSTL tags are not been parsed and they end up plain in generated HTML output?
You need to declare JSTL taglib in top of the JSP page where you're using JSTL tags to get them to run. For the JSTL core taglib, that'll be
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
I am not sure but, Try this...
index.jsp
<jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" />

Categories