かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

PrimeFacesでJavaScriptと連携

JavaScriptからRPCみたいなことをしたあげく、サーバーサイドのコンポーネントツリーの変更を画面に反映したいとき〜!に使えます。

p:remoteCommand

PrimeFacesには、remoteCommandという部品があって、こいつを使うと、タグを書くだけで管理ビーンのメソッドを呼び出しつつ、結果をajaxで返して更新してくれるJavaScript関数が定義できます。

こんな風につかいます。

<p:remoteCommand name="sendMessage" action="#{remoteCommandTestPage.sendMessage}" update="out" />

nameがJavaScriptの関数名で、actionが呼び出したいメソッドをEL式で指定、updateで更新するコントロールのIDを設定します。

作ってみたコード全体

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <p:remoteCommand name="sendMessage" action="#{remoteCommandTestPage.sendMessage}" update="out" />
            <h:outputText id="out" value="#{remoteCommandTestPage.message}" />
            <p:separator />
            <input type="text" id="message" />
            <button id="sendButton">ok</button>
        </h:form>
        
        <script type="text/javascript">
            $(function(){
                $("#sendButton").click(function() {
                    sendMessage([{name: "message", value: $("#message").val()}]);
                    return false;
                });
            });
        </script>
    </h:body>
</html>

意味もなくjQueryでボタンのクリックイベントからテキストボックスに入力された値を送信しています。サーバー側にパラメータを渡すのにnameとvalueのプロパティをもったオブジェクトの配列を渡せるのも便利なポイントです。

サーバーサイドではFacesContextからパラメータを取得して処理をしまう。

package com.mycompany.richtest;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class RemoteCommandTestPage {
    private String message;
    public void sendMessage() {
        message = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("message");
        System.out.println("message: " + message);
    }
    

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

感想

最近の流行りは、JavaScriptでクライアントサイドはいろいろやってサーバーとは、REST APIでってのですが、そういう開発モデルにどうしても慣れれないって人や色々なしがらみがある人は、こういうのを使って既存のプログラムとかとつないでみるのもいいのではないでしょうか。