Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

JSFで改行

こんな基礎的なことでも何がベストな方法か迷う自分が悲しくなる今日この頃…。
そしてJSTL(JSP Standard Tag Library)の関数なるものがJSFでも使えることを初めて知りました orz

まだまだ知らないことだらけだなぁ…。

Twitterでコメントもらったりしたので、追記しました。
以下6つで実際に試しました。

  • CSSのwhite-spaceプロパティ
  • JSTLの関数(replace)で処理
  • pre要素
  • カスタムコンバータで処理
  • Util系CDIで処理
  • メソッド呼出し

とりあえずメモのため、良い例ではないですが以下のようなバッキングビーンを準備。

@Named
@RequestScoped
public class IndexBean {

    @Getter @Setter
    private String inputVal;
    
    @PostConstruct
    public void init(){
        inputVal = "あいうえお\nかきくけこ";
    }
}

画面のラベル表示とかで改行コードで改行するように表示したい場合。
HTMLなんで<br>だべ。
というのはWeb初心者といえどわかるけど、どーやるのがベストなんだろーと。

StackOverflowでこんなのがありました。

CSSのwhite-spaceプロパティ

CSSファイルを作ってresources配下に置きます。

f:id:kikutaro777:20130829205424j:plain

定義は

.preformatted{
    white-space: pre;
}

として

JSFのビューでCSSの宣言して

<h:outputStylesheet library="css" name="format.css"/>

styleClassで指定

<h:outputLabel value="#{indexBean.inputVal}" styleClass="preformatted"/>

これで

f:id:kikutaro777:20130829205551j:plain

と表示できます。改行に限らず半角スペースやタブもそのまま表示。

JSTLの関数(replace)で処理

こっちはugly(醜い、不細工な)な方法だ、と書いてありましたが、そもそもJSFでこういうの書いていいんだ…と今更ながらに(^^;

タグライブラリの定義にfnを入れて

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions">

こんな感じに書く

<h:outputLabel value="#{fn:replace(indexBean.inputVal,'\\n','&lt;br/&gt;')}" escape="false"/>

結果はCSSの方法と同じです。

こちらはescape属性でfalseを明示的に指定するので、何か入力テキストの出力であったりすると気を付けないといけないですね。

pre要素

@megascusさんよりpreで囲んだりコンバータ作ったり、と。
せっかくなので簡単に書いてみました。

<pre>
    <h:outputLabel value="#{indexBean.inputVal}"/>
</pre>

一番最初のCSSのwhite-space preとは違うんですね(^^;色々あってむずい。
以下サイトの途中に違いが簡単に触れられていました。
http://w3g.jp/css/text/white-space

カスタムコンバータで処理

Converterインタフェースを実装して、getAsStringで置換処理を実装したコンバータクラスを作成します。

@FacesConverter(value = "linebreakConverter")
public class LineBreakConverter implements Converter{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return value;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return value.toString().replace("\n", "<br/>");
    }  
}

ビューではconverter属性でID指定するか

<h:outputLabel value="#{indexBean.inputVal}" escape="false"
                           converter="linebreakConverter" />

ネストして定義する。

<h:outputLabel value="#{indexBean.inputVal}" escape="false">
    <f:converter converterId="linebreakConverter" />
</h:outputLabel>

どちらも結果は同じ。

Util系CDIで処理

@den2snさんからはCDIでUtil的なの作るのも、と。
こんな感じでしょうか。

CDI管理対象でreplaceするメソッドを定義して

@Named(value = "utilBean")
@RequestScoped
public class UtilBean {

    public String br(String str){
        return str.replace("\n","<br/>");
    }
}

ビューから呼出し

<h:outputLabel value="#{utilBean.br(indexBean.inputVal)}" escape="false"/>

メソッド呼出し

これも@den2snさんから。
EL式でStringのreplaceAllメソッドをそのまま使う形。

<h:outputLabel value="#{indexBean.inputVal.replaceAll('\\n','&lt;br/&gt;')}" escape="false" />

なぜかreplaceではダメでした。。。

色々ある(^^;

今回は改行の一例でしたが、色々なやり方を知っておいて、適材適所で使えれば…って感じですが、中々難しい(-_-;

とりあえずJSTL呼出し知らなかった自分へのメッセージ

金魚本の351ページ辺りから読み直せ!

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村