0

i've the following situation with Freemarker.

When returning to a page in .ftl i send from Java a parameter to the url, similar to "AAA% BBB@DDD.COM", in Java it is ok.

When looking at the Url it does instead Write : "AAA%25+BBB@DDD.COM" And then with the following code:

<#if myCase??>
    value = ${user}
</#if>

It does write in my html field "AAA%" but not the remaining.

How can i try to solve this issue? Thanks in advance.

EDIT: After further investigations i do see the code i put before does write this on the Html:

value="AAA%" BBB@CCC.com=""

EDIT2: Let'see if i can give you more informations, first of, here's the relevant Java code :

Map mapping = new HashMap();
if(user != null && !user.isEmpty()){
 mapping.put("user",user); //EG: AAA% BBB@DDD.COM (Checked in debug)
}

I have an URL similar to : mysite.xx?user=AAA%25+BBB@DDD.COM so the user it's attached as query param of the url.

I do need to reuse the "user" param to repopulate the Form field relative to the username, this is not a valid email i know, but an alias system already installed by the customer does the aliasing system this way.

Goikiu
  • 574
  • 3
  • 12
  • Would be nice to have the part of **Java-code** where you set the _variable/model_ as well the **full template (FTL)**. Which output do you use, HTML? – hc_dev Feb 28 '19 at 14:23
  • Yes, i do use HTML as output, i cannot put the full template but i can give more snippet when necessary. – Goikiu Feb 28 '19 at 14:24
  • Please post the lines from Java where you define the value to _user_ variable; see [mcve]. Is it defined as a String `String user = "AAA% BBB@DDD.COM";` or as URL like `URL user = new URL( "AAA%25+BBB@DDD.COM");` ?? – hc_dev Feb 28 '19 at 17:22

1 Answers1

1

What could be the cause of the problem

Given your template:

<#if myCase??>
    value = ${user}
</#if>

Output written by Freemarker in output-mode HTML results in following:

value = AAA% BBB@DDD.COM

Freemarker does not understand that (from your context) the value of user should be an attribute-value (assignment). Instead it treats the contents of string user as HTML itself (this could be complete HTML-source as input-field, single tags, etc.). It simply pastes the contents of the model at the position in your template where you have set the variable-interpolation ${user}.

The Freemarker-result is no valid HTML (attribute-value pair), because each attribute should adhere some naming-conventions (i.e. no special-characters). When the attribute has a value, it is followed by an equal-sign and this followed by the value enclosed in double-quotes.

So most browsers convert your result into a valid HTML attribute - actually two attributes: value="AAA%" and BBB@CCC.com="". Opened the output-HTML in Firefox, you will see this in Inspector (NOT IN the raw source-view):

<input type="text" value="AAA%" bbb@ddd.com="">

What is not the cause

FreeMarker is auto-escaping (escpecially when in OutputMode HTML) when it writes the final HTML.

@ddekany Thanks for your comment ! It made me reproduce and discover the real cause.

URL encoding/decoding

In Java you could even encode the string variable user. So it converts % (i.e. percent-sign followed by space) into %25+ which is valid to be used inside an URL.

Run this java snippet online on IDEONE to the effects of URL-encoding and URL-decoding.

Solutions

Use either of these solutions to get desired output by fixing the HTML-attribute value-assignment in your template:

(1) use double-quotes:

   <#if myCase??>
       value="${user}"
   </#if>

(2) use some built-ins to transform the plain string-output:

Use some of FreeMarker's built-ins for strings. In your case you could append ?url to the variable-name and use double-quotes around your variable-interpolation within your template, e.g.:

   <#if myCase??>
       href="mailto:${user?url}"
   </#if>

Caution: validate URL or email-address (even parts of it) as early as possible

BBB@DDD.COM is a valid email-address. But % and whitespaces are not allowed inside an email-address.

On the other side @ is typically not part of an URL, except as part inside a query-param value. But your user (URL) does not start with http:// etc.

So depending on the use-case/purpose of your (so called URL) user with value AAA% BBB@DDD.COM it could finally represent part of an URL or email-address.

In your special case, said:

populate the form field relative to the username. Model-variable user does not contain a valid email-address. It is used in conjunction with an alias system already installed by the customer. So aliasing will work this way.

Let's suppose the end-user which does later edit the form-field is responsible of making it valid (or a script does this validation).

Anyway bear in mind that an internet-address (like URL/email) needs some validation:

  • either before written to the final HTML (using Java or Freemarker)
  • or after being further processed inside your web-page (using JavaScript).

Otherwise it could possibly not yield the desired effect.

See also

Related questions:

hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • It seems that my case is similar to userA. From Java i do Export "AAA% BBB@DDD.COM", on URL i do have "AAA%25+BBB@DDD.COM", what i need to print on html is again "AAA% BBB@DDD.COM" – Goikiu Feb 28 '19 at 15:09
  • Thanks, in my case it works fine this way <#if myCase??>value = "${user}"#if> – Goikiu Mar 01 '19 at 07:21
  • 1
    It has nothing to do with FreeMarker, it doesn't do any such magic. Auto-escaping escapes characters special to HTML (`<` `&` `>` `"` `'`) when you print something with `${...}`, and that's it. It doesn't care about `%`, `=`, etc. – ddekany Mar 01 '19 at 07:31
  • @ddekany: Thanks for your feedback. I updated my answer. Hopefully more comprehensible and helpful to others! – hc_dev Mar 01 '19 at 12:19
  • @hc_dev Yes, now it's correct. Just as a side note (not related to the original question), without auto-escaping on, this will break if `value` contains `"`: `value="${user}"`. If auto-escaping (or `#escape`) is not used, the safe form is this: `value="${user?html}"`. – ddekany Mar 02 '19 at 15:28