Search code examples
jqueryjsf-2primefacescharacter-encodingatmosphere

Primefaces push encoding


I use primefaces push to write a message in a p:notificationBar. if i push a message with specials characters (like russians char), I've got '?' in my message. How can I fix this problem ? Thanks for your help.

(config : primefaces 3.4 and jsf2. All my html pages are utf8 encoding).

Here is my view code :

<p:notificationBar id="bar"
                widgetVar="pushNotifBar"
                position="bottom"
                style="z-index: 3;border: 8px outset #AB1700;width: 97%;background: none repeat scroll 0 0 #CA837D;">
            <h:form prependId="false">
                <p:commandButton icon="ui-icon-close"
                            title="#{messages['gen.close']}"
                            styleClass="ui-notificationbar-close"
                            type="button"
                            onclick="pushNotifBar.hide();"/>
            </h:form>
            <h:panelGrid columns="1" style="width: 100%; text-align: center;">
                <h:outputText id="pushNotifSummary" value="#{growlBean.summary}" style="font-size:36px;text-align:center;"/>
                <h:outputText id="pushNotifDetail" value="#{growlBean.detail}" style="font-size: 20px; float: left;" />
            </h:panelGrid>
        </p:notificationBar>
        <p:socket onMessage="handleMessage" channel="/notifications"/>

        <script type="text/javascript">
            function handleMessage(data) {
            var substr = data.split(' %% ');
            $('#pushNotifSummary').html(substr[0]);
            $('#pushNotifDetail').html(substr[1]);
            pushNotifBar.show();

            }

        </script>  

and my Bean code :

public void send() { 
        PushContext pushContext = PushContextFactory.getDefault().getPushContext(); 
        String var = summary + " %% " +  detail;
        pushContext.push("/notifications", var);

Solution

  • This is the solution that does not rely on Atmosphere framework (used by Primefaces) encoding mechanisms probably responsible for your problem.

    The idea is to push message as Base64 encoded string and to decode it on user side using java script.

    1.Encode your message string using Base64 and push it

    public void send() { 
        PushContext pushContext = PushContextFactory.getDefault().getPushContext(); 
        String var = summary + " %% " +  detail;
        byte b[] = var.getBytes("UTF-8");
        byte b64[] = Base64.encodeBase64(b);
        String message = new String(b64);
        pushContext.push("/notifications", message);
    }
    

    Base64 encoder you can find in org.apache.commons.codec library and import it in your java code using

    import org.apache.commons.codec.binary.Base64;
    

    2.When message arrives on client side decode it using following java script

    <script type="text/javascript">
        function handleMessage(data) {
          var decodedmessage=b64_to_utf8(data);
          var substr = decodedmessage.split(' %% ');
          $('#pushNotifSummary').html(substr[0]);
          $('#pushNotifDetail').html(substr[1]);
          pushNotifBar.show();
        }
    
        function b64_to_utf8( str ) {
          return decodeURIComponent(escape(window.atob( str )));
        }
    </script> 
    

    Please note that Base64 decoding function window.atob is not browser independent solution. For more details about this you can visit here.