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

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

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

参考リンク

http://noknow.info/it/2015/javaee7_jsf2_2_use_resourcebundle_of_utf8file_ja.html

Code

2018/4/17 追加

Bitbucket

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