0

I am using JSF with glassfish 4.0. The following fragment of code

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    ...skipped...
    </h:head>
    ...skipped...
    <h:outputLink value="#{item.lastInstance.url}" escape="false">
        #{item.lastInstance.refName}
    </h:outputLink>

is expected to be translated as:

    <a href="https://url-unescaped>refname-unescaped</a>

but it is translated as:

    <a href="https://url-escaped>refname-unescaped</a>

Bean's url and refName both contains russian text in UTF-8 with spaces and other symbols not allowed in url. But those unescaped links are tested in browsers to work (Firefox 24.0). Escaped sequences are interpreted by browser somehow and doesn't work.

How can I either:

  1. Tell JSF to not escape h:outputLink value
  2. Tell browser that URL(s) is escaped

Thanks for any help.

im_3772071
  • 11
  • 4
  • I do not consider, browser does ;-). When I enter that awful (unescaped, UTF-8-encoded with national symbols and spaces) URL in it's address string it replies with document I want. Anyway I have option 2 in my question: to tell browser that url is escaped. – im_3772071 Jul 14 '14 at 10:30
  • URL is valid. If it is entered in browser's addr line and desired resource is GETted it is considered valid I think. The fact is, that this url is construted by bean by concatenating the http://server/app+path_part+filename_part. server_part and path_part are always ascii. But the filename_part is derived from name of a file uploaded by user. Name of the file is a valid unix filename (national symbols allowed). Thus, I think, URL itself is valid. Following the letter of specifications, unescaped representation of it is invalid. – im_3772071 Jul 14 '14 at 10:53
  • The problem is probably that I see in html source correctly escaped url like this "server_path_part/%D0%A1%D1%87%D0%B5%D1%82%20%D1%82%D1%80%D1%83%D0%B1%D1%8B.jpg" but when link is hovered link is like "server_path_part/!G5B B%40C1K.jpg". And I have to understand how can I either ... – im_3772071 Jul 14 '14 at 11:09

1 Answers1

1

if I don't misunderstand you just want to "Tell JSF to not escape h:outputLink value".

use html <a/> tag instead of <h:outputLink/>

xhtml:

<h:outputLink value="русский.doc">русский.doc</h:outputLink>
<a href="#{jsfUrlHelper.getViewUrl('/русский.doc')}">русский.doc</a>

generated output:

<a href="%40%43%41%41%3A%38%39.doc">русский.doc</a> <!-- h:outputLink -->
<a href="http://localhost:8080/MyApp/русский.doc">русский.doc</a> <!-- a tag -->

JsfUrlHelper.java

import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

@ManagedBean
public class JsfUrlHelper {

    public String getViewUrl(String viewId) {
        return getViewUrl(viewId, null);
    }

    public String getViewUrl(String viewId, String urlParams) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        String contextPath = ctx.getExternalContext().getRequestContextPath();

        StringBuilder url = new StringBuilder(100);

        url.append(getRootUrl(ctx));
        url.append(contextPath);
        url.append(viewId);

        if (urlParams != null && urlParams.length() > 0) {
            url.append("?");
            url.append(urlParams);
        }

        return url.toString();
    }

    public String getRootUrl(FacesContext ctx) {
        HttpServletRequest request = (HttpServletRequest) ctx.getExternalContext().getRequest();

        StringBuilder url = new StringBuilder(100);
        String scheme = request.getScheme();

        int port = request.getServerPort();

        url.append(scheme);
        url.append("://");
        url.append(request.getServerName());

        if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) {
            url.append(':');
            url.append(port);
        }

        return url.toString();
    }
}
bhdrk
  • 3,415
  • 26
  • 20
  • Thanks a lot. Nice workaround. BTW, as I see from your (as well as mine) samples, JSF encodes h:outputLink value to smth "8bit escaped". Is there a way to tell it to encode to "7bit escaped" or do not encode at all? – im_3772071 Jul 14 '14 at 15:43