vue.jsでURLのシャープ#(hashbang)を消したい

vue.jsでvue-routerを使用する際にデフォルトではhash modeとなるためURLに#が付加されます。#を使用したURLが嫌な場合はmodeをhistoryに変更することでURLに#を付加しないようにすることができます。


modeを変更するにはVueRouterの指定で以下のようにモードを指定します。

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})


historyモードではhistory.pushState APIを使用して
hash modeと同様にページリロードなしにURLの書き換えを行うことができます。

Java SE 9のリリースが2017年9月21日に延期

Java SE 9のリリーススケジュールが予定の7月27日から9月21日に変更となりました。
http://mail.openjdk.java.net/pipermail/jdk9-dev/2017-June/005867.html

今年のJavaOne直前となります。


2016/05/26 Feature Complete
2016/12/22 Feature Extension Complete
2017/01/05 Rampdown Start
2017/02/09 All Tests Run
2017/02/16 Zero Bug Bounce
2017/03/16 Rampdown Phase Two
2017/06/22 Initial Release Candidate
2017/07/06 Final Release Candidate
2017/09/21 General Availability

Java Day Tokyo 2017無事終了

Java Day Tokyo 2017無事終わりました。

ありがたいことに私のセッションは満員御礼でした。嬉しい限りです。タイトルが「Java EEにおけるフロントエンド開発とJSF2.3アップデート」だったので、もう少しJavaScriptフレームワークの話も織り込んでも良かったかもしれませんが、今回はJSFを知ってもらおうということでJSFメインで話をしました。


資料が公開されているので興味のある方は是非ご確認ください。
Java Day Tokyo 2017
http://www.oracle.com/technetwork/jp/ondemand/online2017-javaday-3719599-ja.html

Java Day Tokyo 2017で登壇します

2017年5月17日にJava Day Tokyo 2017が開催されます。


www.oracle.co.jp


昨年も登壇させていただいたのですが、今年も機会をいただきお話しさせていただけることになりました。「Java EEにおけるフロントエンド開発とJSF2.3アップデート」というタイトルで、今年7月にリリース予定のJava EE 8に含まれるJSF2.3のアップデートについてお話しさせていただきます。


登録無料ですのでご興味のある方は是非ご参加ください。

Java SE 9とJava EE 8のリリーススケジュール

Java SE 9とJava EE 8のリリーススケジュールですが、
2017/2/24現時点ではどちらも2017年7月予定となっています。


(追記)Java SE 9のリリースは2017年9月21日に延期になりました。


今年の7月は忙しくなりそうです。

JDK 9 release schedule
http://mail.openjdk.java.net/pipermail/jdk9-dev/2016-October/005092.html

2016/05/26 Feature Complete
2016/12/22 Feature Extension Complete
2017/01/05 Rampdown Start
2017/02/09 All Tests Run
2017/02/16 Zero Bug Bounce
2017/03/16 Rampdown Phase 2
2017/07/06 Final Release Candidate
2017/07/27 General Availability

Java EE 8 schedule
https://java.net/projects/javaee-spec/lists/jsr366-experts/archive/2017-02/message/0
 Public Review - Apr/May 2017
 Proposed Final Draft - June 2017
 Final Release - July 2017

Java EE 7 徹底入門と初執筆について

この記事は「Java EE Advent Calendar 2015 - Qiita」の14日目のエントリーです。
昨日は@kabaoさんで、「Javaバッチの実行環境 EEなのかSEなのか」でした。
明日はaf-not-foundさんです。


本日は、明日(12/15)刊行となるJava EE 7 徹底入門についての紹介と、私がその初執筆で感じた事について書きたいと思います。

とうとう出るよJava EE 7 徹底入門!

私が執筆を一部担当させていただいたJava EE 7 徹底入門という本が明日!(12/15)発売になります。


Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築


「とうとう」と書いたのは、この書籍の話をいただいたのが2014年10月ですので、かれこれ1年以上かかった事になります。長かったー(>_<)!


本書は、日頃Javaコンサルタントをしているメンバーで、Java EEを始めて学ぶ方、またはこれから開発をJava EEに移行しようと考えているアーキテクトの方を対象にJava EEの全体像を理解してもらうことを目的に書きました。全体像とは言ってもJava EE 7の全仕様を満たしたものではなく、その中で重要だと思われるJSF,EJB,CDI,JPA,JAX-RS,JBatchについて詳細に解説しています。各章立ては以下のようになっています。(全10章)


Chapter 1 Java EEの基礎知識
Chapter 2 プレゼンテーション層の開発――JSFの基本
Chapter 3 プレゼンテーション層の開発――JSFの応用 その1
Chapter 4 プレゼンテーション層の開発――JSFの応用 その2
Chapter 5 ビジネスロジック層の開発――CDIの利用
Chapter 6 ビジネスロジック層の開発――EJBの利用
Chapter 7 データアクセス層の開発――JPAの基本
Chapter 8 データアクセス層の開発――JPAの応用
Chapter 9 RESTful Webサービスの開発
Chapter10 バッチアプリケーションの開発


私が担当したのは2〜4章のJSFの部分です。Java EE 7の仕様は膨大で、一冊の本にすべて収めることは困難です。今回は本全体を通して簡単なサンプルアプリを1つ作成し、その中で利用可能なアーキテクチャを中心に説明するという方針をとりました。(JSFの章については使用していない機能もけっこう突っ込んで記載してしまいましたが...)


JSFの2〜4章でだいたい150ページくらいでしょうか。当初の予定では80ページくらいに抑える予定でしたが、書きたいことを書き切ったら結局1章分増えてしまいました。なるべくノウハウなども詰め込んで記載したつもりなので、これからJava EEを始める方の参考になればと思っています。

執筆ってどうなの?初執筆で感じた感想

今回の「Java EE 7 徹底入門」は私にとって初めての執筆でした。当初は執筆に興味はありましたがどのようなスケジュールで刊行まで進むのか全くわからず、興味半分、不安半分という感じでした。

思っていた通り大変でした

想定はしていましたが予想通り大変でした。今回の執筆はプライベートでの執筆なので土日を使って作業しましたが、計算では150ページの本を書こうとすると本のサイズにもよるらしいですが本書だとだいたい1ページ1000文字くらい必要になります。だいたい1日頑張っても10000文字くらい書けるかどうかという感じなので2ヶ月近いの土日がすべてなくなってしまいます。実際は1日そんなに書くことはできず「数時間検証作業をして、15分記載」のような繰り返しが続くのでさらに時間を割いたと思います。特に妻子持ちの私としては土日が潰れると家族の不満もたまってくるのでそのバランスを取るのもとても大変でした。

想定外にかかるその他の作業

文章の校正作業というのをまったく意識していませんでしたが、かなり時間がかかりました。レビューの指摘で1項まるまる書き直したり、自分の書いた章を校正するだけでも一字一句丁寧に確認する必要があるので150ページあると普通に1日かかったりしていました。(校正作業中は書き過ぎたのをかなり後悔していました)またサンプルコードの整理や、章と流れをあわせるために他の章も一通り目を通すなど想定外の作業がけっこうありました。

なんだかんだで良い経験となりました

振り返ると大変さしか思い出しませんが、結果として大変多くの新しい経験と知識を得ることができてとても良い経験となりました。このような機会をいただけてとても感謝しています。ありがとうございました。


Java EEをこれからはじめたいと思う方は是非「Java EE 7 徹底入門」を手にとっていただければと思います。


Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

JSFのバリデーション

この記事は「Java EE Advent Calendar 2014」の22日目のエントリーです。
昨日は@suke_masaさんの「続・JPQLでハマった話」でした。明日は@kikutaro_さんです。


今日はJSFのバリデーションについて整理したいと思います。

JSF1.*時代のバリデーション

JSF1.*の時代にはFaceletsのValidateタグを使用してバリデーションを行っていました。例えば5文字以上10文字以下の文字数のチェックを行うプログラムは以下です。

・facelets

<h:form>
  <div>
    <h:inputText id="msg" value="#{hogeBean.msg}">
        <f:validateLength minimum="5" maximum="10" />
    </h:inputText>
    <h:message for="msg" />
  </div>
  <h:commandButton action="#{hogeBean.exec}" value="Exec" />
</h:form>

初期のJSFは画面の作成をGUIで行っていました。そのためバリデーションの設定も画面に持つ事でプロパティで簡単に設定を行う事ができました。

JSF2.0以降のバリデーション

Java EE 6に導入されたJSF2.0からはバリデーションにBean Validationが使えるようになりました。Bean Validationを使用することでJPA等のバックグランドのチェック処理とJSFのチェック処理を共通化出来ます。Bean Validationのチェックは画面側では行わずEL式で紐づくバッキングビーン側のフィールドにアノテーションで設定します。

・バッキングビーン

@Named
@RequestScoped
public class HogeBean {
    @Size(min = 5, max = 10)
    private String msg = "Hello!";
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public void exec() {
    }
}

JSF2.0からは設定より規約が重視されるようになり、GUIに頼らずコードベースで簡単に開発出来るようになりました。そのため、特に画面側にバリデーションを持つ必要性は無くなりました。

Bean Validationでnullチェック出来ない問題

JSFのチェックをBean Validationで行うとすると最初に@NotNullが使用出来ないという問題に遭遇します。具体的には以下のようなソースでは未入力チェックが出来ません。

・バッキングビーン

public class HogeBean {
    @NotNull //未入力チェック出来ない
    private String msg = "Hello!";

これは画面の入力項目がnullではなく空文字として設定されるため発生します。

対処法1 空文字対応のチェックアノテーションを使用する

対処法の1つ目は@NotNullではなく空文字にも対応したアノテーションを使用する事です。たとえばHibernate Validatorで提供されている@NotEmptyを使用すると空文字の場合もエラーにする事が出来ます。

・バッキングビーン

public class HogeBean {
    @NotEmpty //未入力チェック出来できる!
    private String msg = "Hello!";

ただし、@NotEmptyを使用するとJava EE標準ではない実装アノテーションにソースが依存する事になります。

対処法2 INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULLを指定する

web.xmlのコンテキストパラメータにINTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULLを設定すると、サブミットされた値が空文字であった場合に,JSF内でnullに変換してくれます。そうする事で@NotNullで未入力のチェックを行う事が出来ます。

・web.xml

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

・バッキングビーン(@NotNullのまま)

public class HogeBean {
    @NotNull //未入力チェック出来きる!
    private String msg = "Hello!";

相関チェック

JPAではエンティティを引数に渡すと設定してあるチェックは一通り実施してくれますが、JSFではEL式でフィールド単位に紐付けを行うため単項目チェックしか実施されません。対処法はいくつかありますが、今回はBean Validationで2つの項目が同じ値でないとエラーとなるバリデーションを作成してみます。

・Bean Validation用アノテーション

@Documented
@Constraint(validatedBy = {EqualsValidator.class})
@Target({FIELD})
@Retention(RUNTIME)
public @interface Equals {
  String message() default "同じ値ではありません";
 
  Class<?>[] groups() default {};
 
  Class<? extends Payload>[] payload() default {};
 
  String value();
 
  @Target({FIELD})
  @Retention(RUNTIME)
  @Documented
  public @interface List {
    Equals[] value();
  }
}

・Bean Validation実装

public class EqualsValidator implements ConstraintValidator<Equals, String> {
 
    private String target;

    @Override
    public void initialize(Equals equals) {
      target = equals.value();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        UIComponent currentComponent = UIComponent.getCurrentComponent(FacesContext.getCurrentInstance());
        if (currentComponent != null) {
            //同階層にあるUIComponentを検索
            UIComponent component = currentComponent.getParent().findComponent(target);
            if (component != null && component instanceof UIInput) {
                UIInput uiInput = (UIInput) component;
                Object targetValue = uiInput.getSubmittedValue();
                //SubmittedValueがnullの場合は検証後のデータを取得
                if(targetValue == null) {
                    targetValue = uiInput.getValue();
                }
                //指定された項目と同じ値かをチェック
                if (value == null) {
                    return targetValue == null || targetValue.equals("");
                } else {
                    return value.equals(targetValue);
                }
            }
        }
        return true;
    }
 
}

・利用例(サーバ側)

public class TestData implements Serializable {
    private String val1;
    @Equals("val1")
    private String val2;

・利用例(画面)

<h:form id="form">
    <h:inputText id="val1" value="#{checkBean.testData.val1}" /><h:message for="val1" /><br />
    <h:inputText id="val2" value="#{checkBean.testData.val2}" /><h:message for="val2" /><br />
    <h:commandButton action="#{checkBean.check()}" value="送信" />
</h:form>

・実行結果
f:id:den2sn:20141221102913p:plain

val1とval2が同じでないとエラーになります。
なんとか作成できましたが、JSF依存の実装で、かつコンポーネントの配置やIDを意識する必要があるので微妙な作りとなってしまいました。JSFの正式対応が望まれます。