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

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

JSF(Form)

アイディアメモ(随時更新)

ViewForm

@Label

  • 独自のアノテーション@Labelはメッセージ出力時の対象項目名として使用する
  • 表示名は表示にのみ使用するものでありドメインでは無いと考えた
  • 表示名はResourceで管理する
  • クラスパスと同じフォルダ構成でファイルを作成する
  • ファイル名はクラス名と同じにする
  • aptコンパイル時にResourceが存在しない場合は警告を標準出力する(エラーにはしない)
  • Resourceが存在しない場合は表示ラベルとしては、フィールド名をそのまま出力する
  • デフォルトは同構造のパスに格納したものを使用するが、任意の文字列の指定も可能とする*2
    任意の指定をしている場合はResourceを使用しないので警告出力はしない。

画面表示アイテム

  • 固定文字はResourceで管理する。
  • Resourceコンポーネント単位で作成するか、Resourceのキーに画面名を付与してシステムで1つにする。JSFの仕組みで入力補完対象になることを考えたら1つにする方が良い。*3

*1:JavaScriptHTML5でプリミティブ型について、ある程度対応が出来ることは分かっているが、どこで正しくデータを保証するのか?というのを考えた結論として、クライアント(ブラウザ)ではなく、あくまでサーバーサイドで きちんと保証するのが正しいと考えた

*2:Resourceの恩恵は受けられないが、使い捨てシステムの場合には この仕組みを設けておくことで開発が楽にできる。

*3:悩みどころ。移植性を考えたらコンポーネント単位で作成になるけど、細かい資産が増えすぎることと、Resourceが多い事を嫌がる人がそこそこいるような気がする

CDIのメモ

全般

JavaEE7をはじめよう(13) - インジェクション候補が複数ある場合の対処方法 - エンタープライズギークス (Enterprise Geeks)

CDI(Contexts and Dependency Injection)まとめ - A Memorandum

なるほど!ザ・Weld | Exploring CDI extensions

@n_agetsu

パーフェクトJavaEECDIパートの著者でもあります。実際に何度か勉強会で話は聞かせていただいたこともあります。とにかく分かりやすいし聞きやすいです。

www.slideshare.net

www.slideshare.net

n-agetsuma.hatenablog.com

Java EE環境におけるCDIのデフォルト化 - 見習いプログラミング日記

CDIとiBATIS2.3を組み合わせる - 見習いプログラミング日記

CDIでアプリケーション設定をインジェクション - 見習いプログラミング日記

インジェクト

コンストラクタインジェクトをつかう

DIコンテナのインジェクション方法の使い分けについて - 日々常々

パーフェクトJavaEE:P47

@xxScopedには@Typedを忘れずに

パーフェクトJavaEE:P49

依存の注入ポイントとなる型(Interface)を明言した方が良さそう。Interfaceと実装が1対1であれば必ず限定できるけど、それだと何のためにDI使っているのか、という話になってしまう。また同じく複数の型(Interfaceや抽象クラス)から具象化されるクラスが意図せず1つという状態になるのも良くない。少なくともScopeを限定している具象クラスにおいては論理的に1対1しておいた方が良い。

なおテストを考えても@Typedを使った方が良い。

CDIでコンストラクタインジェクションしたい - CLOVER🍀

もう少し詳細な情報や使い方

Java EE 7 CDIを使う際の注意点──『Java EE 7徹底入門』番外編 第2回 - page2 - builder by ZDNet Japan

CDIビーンを動的に取得する - ksino's diary

CDIビーンを動的に取得するコードの単体テスト - ksino's diary

BeanManagerでCDIコンテナにアクセスする | なるほど!ザ・Weld

Java Examples for javax.enterprise.inject.spi.CDI

Java EEのCDIで定義しておくと便利なプロデューサーとインターセプタ - きしだのはてな

Java EEアプリケーションで起動時になにかしらの処理をする方法 — 裏紙

JavaSE環境

依存ライブラリが極力少ない方が良いと思うけど、CDIは使った方が良いと思う。JavaEEだけじゃなくてJavaSEでも。

JavaSE 環境でCDI(Weld)を使う - Qiita

JPAのメモ

全般

Java EE 8がそろそろ固まってきたのでJPA 2.2のJavaDocを日本語に翻訳し始めた(2/3完了) - 水まんじゅう2

JavaEE使い方メモ(JPA その1 - 基本) - Qiita

Red Hat JBoss Web Server 1.0 Hibernate Entity Manager リファレンスガイド - Red Hat Customer Portal *1

JavaEE Code探索 その3 〜 トランザクション属性 〜 - A Memorandum

JPA2.1でエンティティからインデックスを自動生成する - 水まんじゅう2

spring-data-jpa アンチパターン - Qiita

はじめてのJPAでちょっと怖い勘違い - ビールとプリンとプログラミング。

JavaEE7をはじめよう(9) - JPA TIPS - エンタープライズギークス (Enterprise Geeks)

EntityManager

JavaEE7をはじめよう(14) - Producerの効果的な利用方法 - エンタープライズギークス (Enterprise Geeks)

複数のEntityManagerを切り替える(on CDI) - edgegram

JAX-RS(Jersey)とJPAのサンプルにCDIを使ってTomcatで動かす - Qiita

JPAとJTAをJavaSE環境で使えるようにする: すふぃあの記憶

@RequestScopedにする。

トランザクション

JavaEE使い方メモ(JTA) - Qiita

Jerseyでリソースメソッドをトランザクション境界にする — 裏紙

大量処理

JPAで少しずつデータを処理する方法を考える - 見習いプログラミング日記

メモリを逼迫させずにJPAで大量データを取得する方法 - エンタープライズギークス (Enterprise Geeks)

Native Query

JavaEE7をはじめよう(5) - JPAクエリ(その2) Native Query - エンタープライズギークス (Enterprise Geeks)

SQL文を外部ファイルに | 老いぼれSEの艱難辛苦

Builderパターン

JPA Builder パターン

トランザクション

[Spring] 宣言的トランザクションがネストした時はどうする!? REQUIRES_NEWを使ってみた | DevelopersIO

わかりやすい JPA(12)楽観的ロックと悲観的ロック

作りたい共通部品

  • Listインターフェースを良い感じにパラメータとして設定できるようにする
    (とりあえず、数値と文字列だけ)
  • Listが空の場合はnullin()にならないようにする)*2
  • SQLの参照はパッケージをフォルダにする*3
  • JPABuilderをEntityの情報からAnnotationProcessorで自動生成
  • JPAの型情報からフィールド毎のBeanValidationをAnnotationProcessorで自動生成
    全体でフィールド名が重複している場合はエンティティ名を接頭文字につける。
    同じドメインにしたい場合は、アノテーションドメイン名を指定。重複している場合は「マージ」
    必須(NotNull)は対象外(集約であるEntityにとって必須という扱いと考えるから)
  • Eneityクラスからテーブル定義的(とりあえずhtml)なものをAnnotiontionProcessorで自動生成。
    (重複しているドメインがある場合、備考にその旨を追記すると後々ありがたい機能になる気がする。)

note

  • SQLファイル読み込みの仕組みはorm.xmlがあるけど使わない(リンクはメモ)。

その他

Spring Data JDBC Preview - Qiita

*1:仕様に目を通すのは大事

*2:Domaの2waySQLを参考

*3:Doma方式を参考

Presentationのスコープについて

Presentation層におけるスコープについて

@ConversationScoped

画面操作に関するスコープとして、また その考察

実装イメージ

  • 開始ポイントを必ずindex.xhtmlにする。
  • ファイル名を除くフォルダパスが変更されるタイミングを@ConversationScopedの開始・終了の境界にする。
  • フォルダ名を宛先(index.xhtmlは省略可能。SAStruts風?)
  • 同一会話内の画面遷移はxhtml名だけで遷移する。.xhtmlの省略不可。
  • 会話開始前にindex.xhtml以外のパスにアクセスをしようとしたら、同一フォルダのindex.xhtmlフォワードする。
  • 画面遷移はリダイレクトするようにInterseptor?faces-redirect=true";を付与する。同一画面遷移(return null)の場合は、自画面パスを取得して対応する
  • サブフォルダも親フォルダの会話範囲にする*1

考察

@ViewScopedJSF依存)は使わない

  • フォルダパスが変わらない=同一画面ということになるので、会話の開始・終了のタイミングは問題なさそう。
  • クライアントに情報を持たないので通信量が少なくて良さそう。

@FlowScopedJSF依存)は使わない

  • 同一会話を同一フォルダまたは子フォルダで表現すれば求めている要件は満たしている。
  • @FlowScopedと違って遷移フローのためのクラスとかXMLを作成しなくていいので分かりやすくなりそう。
  • jarにして部品化することは出来なくなる可能性大?。部品化する場合、仕組みを含めて全て取り込まないといけないことになるのでサイズが大きくなってしまう?。

会話の開始は どうやって?

タイミング

画面初期表示

なぜ

遷移の終了フェーズで開始をしないと、前回の会話をそのまま引き継いでしまう。

Interseptorで実現しようとしたけれど、終了から開始までにフェーズが変わっていないため、前回の会話スコープIDを そのまま引き継いでしまって想定していた挙動が実現できなかった。

どうやって

viewActionで実装。
共通的に扱えるようにするためにテンプレートを使用すればボイラーな実装はしなくてよくなる。

JSF 2.2ではf:eventのpreRenderViewではなくf:viewActionを使う? - DENの思うこと

会話の終了は どうやって?

タイミング

Interseptor

なぜ

処理前後のURLで終了判定をしたいため、処理前後のURLを把握できる場所がInterseptorだから。

また、終了時点で、次の画面に遷移する前に確実に終了させておきたい。

どうやって

処理前の画面URLと処理後のURLのフォルダが異なる場合は会話を終了させる。

画面遷移のルール

遷移というか、パス指定のルールはSAStrutsを参考にしようかと思っています。

随分、昔の話にはなりますが、SAStrutsをやって、EEを見たときに「ほとんど同じじゃない?」と思ったということもあって、親和性がある気がしている。

全く同じにする、というつもりはないけれど、基本的な考え方については色々と参考にしようかな。

Super Agile Struts - Tutorial

フォルダで会話スコープの実装例

2018/5/3 追記
イメージしていることの お試し実装をしてみました。

vermeer.hatenablog.jp

@RequestScoped

単純な参照のみの画面の事を考えて@RequestScopedは残す。

実装イメージ(悩み中)

StatelessViewの強制

Stateless Viewの制御を@RequestScopedを使用した場合に強制的に行うようにInterseptorで対応。

閲覧のみのコントローラーですよ、ということが分かるようにする工夫が必要かな。

@ApplicationScoped

ユーティリティクラス(悩み中)

ユーティリティクラスをInject対象にする状態が、すでに良くない気がしている。でもテスト容易性のためにstaticクラスにしないで、ということはあるかもしれないので、一応想定はしておく。

@SessionScoped

ユーザー情報

  • ログイン以降のユーザーの状態。
  • 認証・認可

ゲストユーザー情報

  • ログインする前の状態保持。ショッピングカート的な仕組みだと必要かも。

*1:2017/8/6 追記:スコープが広すぎるので対象外にするべき?

JJUG ナイトセミナー 「Java O/Rマッパー特集」に参加してきました #jjug

まとめ

【東京】JJUG ナイトセミナー 「Java O/Rマッパー特集」 7/26(水)開催 #jjug - Togetterまとめ

スライド

speakerdeck.com

Doma

www.slideshare.net

www.slideshare.net

スライド(関連)

speakerdeck.com

www.slideshare.net

感想

私が使用しているのはJPAで、話を聞いたうえでJPAで良いかな、と思った。

理由

JPQLとかORMらしさに拘っていない

基底となる技術要素がRDBである以上、実行SQLから目を背けることは出来ないということから、私は割と気軽にNativeQueryを使っている。標準SQLに限ればDB製品依存も言うほど気にしなくて良いと思っている*1
ただコード内で直接文字列操作をするのは好きではないというのと、SQLの確認のやり易さということでSQLファイルを読み込む共通部品は作った。今は、フラットに格納しているけれどDomaのようにパッケージに準じたフォルダで格納するというのは良さそうだから、今後、改修しよう。

テーブルにEntityクラスが1対1にも拘らない

@ReadOnlyをつけたEntityDTOとして参照のためだけに作ってDomaみたいにフラットな結果を後からゴニョゴニョしている。

キャッシュをあてにしない

キャッシュというかEntityManagerが原因で困ることが割とあるので、あてにしない仕組みにしておいた方が無難と思う。例えばflushはちゃんとコールするとか、selectはDBから最新のものを取ってくるようにするとか、そういうこと。

標準だから

JavaEE標準の看板は選定理由として大きい。思考停止していると言われたら その通りだと思う。ORMに対してトランザクションとクラスマッピングの基本的な仕組みしか求めていない私には何かしらルールと実装があれば良いので「標準」は訴求力になる。

あえて「好み」をいうと…

S2JDBCは良かった。2 way SQLが便利だった印象があるので。なので 今回、話を聞いてDomaが良さそうと思った*2
ただJPAを止めてまで、aptベースの仕組みを導入するか?というと難しいかなぁ。apt自体は理解をすると決して尻込みをするような技術ではないし、実際に動くコードが見られるので むしろ安心感すらあるんだけれど、分かってもらうためのハードルが高いかも。apt自体がもっと使いやすくなれば良いんですけどね。
ということもあって、今のところDomaを使うよりもJPAを便利に使えるための仕組みの精錬を優先しようかと思った結果『JPAで良いかな』という結論に至った次第。

*1:実際に移植しているわけではないので困った経験はないけれど

*2:以前、aptの教材・参考としてDomaのコードをみたけれど、ORMとしては既にJPAを使っていた&一通り仕組み作りまでしてしまっていたのでスルーしていたので、今回、話を聞けて良かった。

PaaS

PaaSに関するブックマークとメモ

外部サービスなどを考えるのであれば、PaaSが良いと思う。理由は運用コスト。ローカル環境や社内環境だと自分でカスタマイズできる自由度に惹かれるけれど、時間は有限なので何かしらのトレードオフは必要。ということで、外部・内部に関係なく、サービスを検討する場合には、まず「これはPaaS上でも動くものなのかな?」というところをスタート地点にするのが良いと考えた。 *1

なんて言っているが実際には全く手を付けていない。。情報収集をしては、その情報がどこかにいったりして毎回調べ直し。 ということで、無くさない場所に必要になりそうな情報のメモを残す。

コミュニティ

https://paas.connpass.com

スライド

www.slideshare.net

Cloud Foundry

PaaSをローカル環境で試せる。ただ、私の環境では貧弱すぎる可能性大。

自宅 Cloud Foundry環境を構築する : まだプログラマーですが何か?

GitHub - Pivotal-Japan/cf-workshop: Cloud Foundry Workshop

Bulemix

Bluemixが良いと思うところは、ベースがCloudFoundryだということ。移植性が高そう。また、小さい規模であれば、ずっと無料枠が使えるみたいなところ。

使い方

IBM Bluemix DevOps Services 概要

IBM developerWorks 日本語版 : Cloud computing : Learn

www.slideshare.net

www.slideshare.net

BluemixでJava 8を使う(on Liberty Runtime & DevOps Service)

Java EE

IBM Cloud ライト・アカウント&Java EEアプリのデプロイ #IBMCloud #jjug_ccc - Challenge Java EE !

無料枠

クラウドサービスIBM Bluemixを無料で使うノウハウまとめ

Google Apps Engine

PaaS当初の感動とは別に、癖が強そうということなどもあり、今のところ選定対象から外すことにした。

その他

今のところ、無料枠がネックになって選定外。

*1:GAEが世に出た時には感動に近いものがあったなぁ。

認証・認可のメモ

HTTPステータス

セキュリティ監査で文句を言われないHTTPステータスコードの使い分け - Qiita

HTTPステータスコード - Wikipedia

【Java】HTTPステータスコード列挙型 Powered by Wikipedia - Qiita

認証・認可

OAuth 2.0 全フローの図解と動画 - Qiita

よくわかる認証と認可 | Developers.IO

マイクロサービスで必要になるかなぁって思って僕がOAuth2とOpenID Connectをなんとなく分かるようになるまでの物語 - Mitsuyuki.Shiiba

業務システムにおけるロールベースアクセス制御 - Qiita

Spring SecurityでRBACなサンプルを作ってみた - Qiita

Spring Security 使い方メモ 基礎・仕組み - Qiita

AzureAD for Java

SpringSecurityでFORM認証 - SIerだけど技術やりたいブログ

http://kimulla.hatenablog.com/entry/2016/05/08/SpringSecurity_%E6%A8%A9%E9%99%90%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%84%E3%81%A6%E8%AA%8D%E5%8F%AF%E5%87%A6%E7%90%86%E3%82%92%E3%81%99%E3%82%8B

Google API OAuth2.0のアクセストークン&リフレッシュトークン取得手順メモ - Qiita

第一回 認証基盤のこれからを支えるOpenID Connect | オブジェクトの広場

トークンを利用した認証・認可 API を実装するとき Authorization: Bearer ヘッダを使っていいのか調べた - Qiita

図解:OAuth 2.0に潜む「5つの脆弱性」と解決法 (1/4):デジタルID最新動向(2) - @IT

「モバイル、オープンAPIを活用するための認証基盤(標準技術 OpenID Connect、OAuth 適用の考え方)」セミナーを開催しました(10月19日@東京) | オージス総研

OpenID Connectユースケース、OAuth 2.0の違い・共通点まとめ - Build Insider

www.slideshare.net

java-oauth-server/README.ja.md at master · authlete/java-oauth-server · GitHub

アプリケーションにおける権限設計の課題 - kenfdev’s blog

レルム

たかがレルムされどレルム GlassFish で始める詳細 JDBC レルム | 寺田 佳央 - Yoshio Terada

Jersey MVCでレルム認証する(Jerseyも基本的には方法は同じ!) - Instructor's memo

レルムを使用したユーザ管理とユーザマッピング

実装例など

Javaの道:Tomcat(13.JDBCレルムによるFORM認証)

Java アプリケーションコンテナに依存しないユーザー認証 : まだプログラマーですが何か?

6.10. 代表的なセキュリティ要件の実装例 — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.1.0.RELEASE documentation

さいきょうの二重サブミット対策 - Qiita

猶予8時間!脆弱性だらけのサービスを堅牢化する実践型研修 - Speee DEVELOPER BLOG

JavaEEでリクエストのHTTPヘッダに値を付加する - No Programming, No Life

GitHub - making/oauth2-sso-demo: OIDC SSO Demo with Spring Boot + Spring Security + Spring Cloud Gateway

www.slideshare.net

https://gist.github.com/backpaper0/afd3c6afb71129add2e0d4923870a2b9

spring-fest-2017/sample5 at master · backpaper0/spring-fest-2017 · GitHub

認証局

SSL/TLS化しているサイトにリクエストを投げたら証明書の検証にしくじっているという時 - その手の平は尻もつかめるさ

設定

SpringBootを使うときに最低限やっておきたいセキュリティ対策 - Qiita

パスワード

【Java SE 8限定】安全なパスワードを生成する方法 | キャスレーコンサルティング株式会社