How do I concatenate and sanitize strings in JSTL/EL?
Asked Answered
T

1

6

I have a complicated set of nested functions that essentially sanitize data.

Let's pretend I want to emit a firstname-lastname combination that's been sanitized, but the names are presented as two separate variables.

I realize I could simply emit each variable separately, wrapping each in the entire set of sanitizing functions, but that's both inelegant and dangerous: big chunks of hard-to-read, duplicate code that need to be kept in-sync over the lifetime of the app.

In a real language, I would write something like this:

${fn:trim(fn:replace(fn:replace(fn:replace(fn:replace(firstname + lastname, ..., ...), ..., ...), ..., ...), ..., ...))}

(Here, the plus represents a true-blue concatenation operator; javascript's '+', PHP's '.', etc.)

It also seems kind of absurd to use a separate statement to merely concatenate the variables beforehand.

Bottom line: this question has been asked a thousand times on the internet, but all the answers effectively dodge the question by proposing an alternative implementation. I want to know if this feature exists, and the documentation is worse than trivial.

Please, end my suffering and give me a straight answer.

Thallic answered 8/2, 2012 at 17:12 Comment(1)
This is not the job of a JSP. Do it in Java, in a servlet or action of your preferred MVC framework, and just display the prepared, sanitized result in the JSP.Sensillum
C
22

What exactly do you want to sanitize? HTML/XML special characters like <, > and so on to prevent XSS holes? If so, why not just using <c:out>?

<c:out value="${firstname} ${lastname}" />

If there's really more into the picture, cleanest would be to refactor that job into a public static utility method, register it as an EL function and invoke it.

E.g.

public final class Functions {

    private Functions() {
        // Hide c'tor in utility classes.
    }

    public static String sanitizeNames(String firstname, String lastname) {
        // TODO: Implement.

        return sanitizedFirstname + sanitizedLastname;
    }

}

which is registered as follows in a /WEB-INF/functions.tld file

<?xml version="1.0" encoding="UTF-8" ?>
<taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

    <display-name>Custom Functions</display-name>    
    <tlib-version>1.0</tlib-version>
    <uri>http://example.com/functions</uri>

    <function>
        <name>sanitizeNames</name>
        <function-class>com.example.Functions</function-class>
        <function-signature>java.lang.String sanitizeNames(java.lang.String, java.lang.String)</function-signature>
    </function>
</taglib>

and is used as follows

<%@taglib uri="http://example.com/functions" prefix="f" %>
...
${f:sanitizeNames(firstname, lastname)}
Crowbar answered 8/2, 2012 at 20:20 Comment(1)
I didn't pursue this solution in the case that prompted my question, but I very much appreciate your details on the approach. I will likely use it in the future. :)Thallic

© 2022 - 2024 — McMap. All rights reserved.