読者です 読者をやめる 読者になる 読者になる

システム開発で思うところ

JavaEEを主にシステム開発をしながら思うところをツラツラを綴る

JSFでResourceBundleを適用する

前回は、全部入りのResourceBundleを作ってみました。

vermeer.hatenablog.jp

今回は、そのResourceBundleをJSFで使えるようにするためのパーツとサンプル実装を作りました。ほとんどは、参考リンクのままです。

ResourceBundleのファクトリークラス

/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *  Copyright © 2016 Yamashita
 */
package com.mycompany.samplejsf.infrastructure.jsf.uicomponet;

import com.mycompany.samplejsf.infrastructure.resourse.CustomControl;
import java.util.Locale;
import java.util.ResourceBundle;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * JSFで参照するResourceBundleを生成するFactoryクラス.<br>
 * 本クラスで生成したクラスを{@literal faces-config.xml}に設定してJSFから参照する.<br>
 *
 * @author Yamashita
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class JsfResourceBundle {

    /**
     * ResourceBundleを生成する.<br>
     * 取得方法の制御については、CustomControlで指定をする.<br>
     *
     * @see com.mycompany.samplejsf.infrastructure.resourse.CustomControl
     *
     * @param bundleBaseName 取得対象のResourceBundleのBaseName(AAAA.propertiesのAAAAの部分)
     * @param customControl 必要情報を設定したCustomControl
     * @return 生成したResourceBundle
     */
    public static ResourceBundle getBundle(String bundleBaseName, CustomControl customControl) {
        Locale locale = JsfContextUtil.getLocale();
        return ResourceBundle.getBundle(bundleBaseName, locale, customControl);
    }

    /**
     * ResourceBundleを生成する.<br>
     * Controlを未指定の場合は、文字コードはデフォルト(ascii)、取得対象はpropertiesファイルのみとしてResourceBundleを生成する.<br>
     * 取得対象をpropertiesのみとするのは、検索対象を絞る事で性能改善を図る.
     *
     * @param bundleBaseName 取得対象のResourceBundleのBaseName(AAAA.propertiesのAAAAの部分)
     * @return 生成したResourceBundle
     */
    public static ResourceBundle getBundle(String bundleBaseName) {
        CustomControl customControl = CustomControl.builder()
                .formats(CustomControl.FORMAT_PROPERTIES)
                .build();
        return JsfResourceBundle.getBundle(bundleBaseName, customControl);
    }
}

ResoureceBundleを生成する

/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *  Copyright © 2016 Yamashita
 */
package com.mycompany.samplejsf.domain.resource;

import com.mycompany.samplejsf.infrastructure.jsf.uicomponet.JsfResourceBundle;
import java.util.Enumeration;
import java.util.ResourceBundle;

/**
 * 表示ラベルResourceBundle
 *
 * @author Yamashita
 */
public class LabelResourceBundle extends ResourceBundle {

    public LabelResourceBundle() {
        ResourceBundle bundle = JsfResourceBundle.getBundle("label");
        super.setParent(bundle);
    }

    @Override
    protected Object handleGetObject(String key) {
        return super.parent.getObject(key);
    }

    @Override
    public Enumeration<String> getKeys() {
        return super.parent.getKeys();
    }
}

propertiesファイルのbaseNameであるlabelを指定します。今回は、デフォルト指定のためCustomControlを使用していませんが、先日作成したCustomControlを引数として使用することで文字コードや参照リソースの絞り込みなどができます。

properties

label.properties

hello=こんにちは
hello.hi=こんにちは、こんちは

message.properties

noselect=選択無し
gender_male=男
gender_female=女

faces-config.xmlを設定する

<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              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-facesconfig_2_0.xsd">

    <application>
        <resource-bundle>
            <base-name>
                message
            </base-name>
            <var>msg</var>
        </resource-bundle>
        <resource-bundle>
            <base-name>
                com.mycompany.samplejsf.domain.resource.LabelResourceBundle
            </base-name>
            <var>label</var>
        </resource-bundle>
    </application>
</faces-config>

xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <head>
        <title>properties label</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <h:form>
            <div>
                <p>#{label.hello}</p>
                <p>#{label['hello.hi']}</p>
                <p>#{msg['gender_male']}</p>
            </div>
        </h:form>
    </body>
</html>

出来るは出来たのですが、msgNetBeans*1で入力補完がされるのですが、独自に拡張したResourceBundleで参照しているlabelについては入力補完がされませんでした。タイプセーフになることを期待したのですが、ちょっと残念です。

実行結果

f:id:vermeer-1977:20161231163714p:plain

参考リンク

[JavaEE7][JSF2.2]UTF8のプロパティファイルを使用してリソースバンドルを使用する

*1:Product Version: NetBeans IDE 8.1(Build 201510222201)