Spring bootはjsp、velocity、thymeleafなどのテンプレートエンジンが使えますが今回はvaadinを使ってみます。 vaadinにspringのtutorial があるのでこれをやってみます。
tutorialのソースコードはgitにおいてあったのでコードが見たい人は以下のレポジトリを見るとよい。https://github.com/vaadin/spring-tutorial
Vaadinとは?
出処: https://vaadin.com/framework
VaadinはUI FrameworkでリッチなViewを簡単に作ることが出来ます。2007年あたりからOSSとして公開されているUI Frameworkです。Vaadinが用意しているUI Componentを使うことでhtml, css, jsと言ったフロント周りのコードを一切書くこと無くJavaだけでリッチなViewを作ることができるのが最大の特徴です。自分たちで使うツールのViewに使ったり、FrontのjsがかけるWebデザイナがいないけど無難なUIが作りたいといった場合に重宝します。
vaadin spring boot tutorial 以下の4章を順にやっていく。
I - Getting Started with Vaadin Spring and Spring Boot
II - Injection and Scopes with Vaadin Spring
III - Views and Navigation with Vaadin Spring
IV - Configuring and Using Vaadin Spring without Spring Boot
プロジェクトを作る springはmaven, gradleプロジェクトであれば以下のアプリを使うことで簡単に雛形を作ることができるのでこれを利用します。http://start.spring.io/
mavenプロジェクトを選択し、Dependenciesにvaadinと入力してプロジェクトをダウンロードすればOKです。mvnコマンドでアーキテクトタイプを調べてといった操作をしなくてもプロジェクトが作れてしまいます。
IDEはSpring Tool SuiteでもEclipseでもintellijでもなんでも良いので、ここではintellijを使います。
CentOS7でOpenjdk8を使う場合はopenjdk-develをインストールする必要があるので以下のコマンドを実行する。
root$ yum install java-1.8.0-openjdk-devel
https://www.jetbrains.com/idea/ でintellijをダウンロードして先の手順で作成したプロジェクトを解凍してmavenプロジェクトとしてインポートします。
UIを作る 早速UIを作ります。
以下の2つのコードをclasspath以下に追加する。
Greeter.java @SpringComponent @UIScope public class Greeter { public String sayHello () { return "Hello from bean " + toString(); } }
@SpringComponentはDIできるようにComponentに登録するアノテーション。 @UIScopeは後ほど説明がある。
MyVaadinUI.java @Theme ("valo" )@SpringUI public class MyVaadinUI extends UI { @Autowired private Greeter greeter; @Override protected void init (VaadinRequest request) { setContent(new Label(greeter.sayHello())); } }
このクラスがUIの雛形になる。このUIに対してView(UIの部品、例えばフォームとかリンクとか)を追加していく。 @ThemeでVaadinが用意しているテーマや自分で作ったテーマを指定する。テーマvaloがカッコいい。
@SpringUIでUIとして登録する。
UIのクラスを作る場合はUIを継承しておく。先に作ったGreeterクラスをDIする。
IDEのMaven Projects -> Plugins -> spring-boot -> spring-boot:runから実行し、http://localhost:8080 に接続すると以下のような文字列が画面が表示される。
Hello from bean com.example.component.Greeter@77215bc
Viewを追加する MyVaadinUI.javaを以下のように変更する。
MyVaadinUI.java @Theme ("valo" )@SpringUI public class MyVaadinUI extends UI { @Autowired private SpringViewProvider viewProvider; @Override protected void init (VaadinRequest request) { final VerticalLayout root = new VerticalLayout(); root.setSizeFull(); root.setMargin(true ); root.setSpacing(true ); setContent(root); final Panel viewContainer = new Panel(); viewContainer.setSizeFull(); root.addComponent(viewContainer); root.setExpandRatio(viewContainer, 1.0f ); Navigator navigator = new Navigator(this , viewContainer); navigator.addProvider(viewProvider); } }
SpringViewProviderがSpringViewを良しなにautowiringしてくれるらしい。
MyVaadinUIにViewを追加する。MyVaadinUIはVerticalLayoutでPanelを追加している。
DefaultViewとして以下のクラスを追加する。
DefaultView.java @SpringView (name = DefaultView.VIEW_NAME)public class DefaultView extends VerticalLayout implements View { public static final String VIEW_NAME = "" ; @PostConstruct void init () { addComponent(new Label("This is the default view" )); } @Override public void enter (ViewChangeEvent event) { } }
http://localhost:8080 に接続するとpanelが追加された以下の画面が表示されることを確認できる。
UIScopeとViewScopeの違い UIScopeはUIに紐づくスコープでViewが変わっても保持されるがViewScopeはViewが変わると保持されず変更されるスコープ。 UIScopeは画面を再読込すると変更される。
ViewScopedView.java @SpringView (name = ViewScopedView.VIEW_NAME)public class ViewScopedView extends VerticalLayout implements View { public static final String VIEW_NAME = "view" ; @Autowired private ViewGreeter viewGreeter; @Autowired private Greeter uiGreeter; @PostConstruct void init () { setMargin(true ); setSpacing(true ); addComponent(new Label("This is a view scoped view" )); addComponent(new Label(uiGreeter.sayHello())); addComponent(new Label(viewGreeter.sayHello())); } @Override public void enter (ViewChangeEvent event) { } }
ViewScopeのViewGreeterを持つView。
ViewGreeter.java @SpringComponent @ViewScope public class ViewGreeter { public String sayHello () { return "Hello from a view scoped bean " + toString(); }
ViewScopeのComponentを作る。ViewScopeなのでViewが更新されるごとにインスタンスが変わる。
UIScopedView.java @UIScope @SpringView (name = UIScopedView.VIEW_NAME)public class UIScopedView extends VerticalLayout implements View { public static final String VIEW_NAME = "ui" ; @Autowired private Greeter greeter; @PostConstruct void init () { setMargin(true ); setSpacing(true ); addComponent(new Label("This is a UI scoped view. Greeter says: " + greeter.sayHello())); } @Override public void enter (ViewChangeEvent event) { } }
UIScopeのGreeterを表示するView。
MyVaadinUI.java public class MyVaadinUI extends UI { ... @Override protected void init (VaadinRequest request) { final VerticalLayout root = new VerticalLayout(); root.setSizeFull(); root.setMargin(true ); root.setSpacing(true ); setContent(root); final CssLayout navigationBar = new CssLayout(); navigationBar.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); navigationBar.addComponent(createNavigationButton("UI Scoped View" , UIScopedView.VIEW_NAME)); navigationBar.addComponent(createNavigationButton("View Scoped View" , ViewScopedView.VIEW_NAME)); root.addComponent(navigationBar); final Panel viewContainer = new Panel(); viewContainer.setSizeFull(); root.addComponent(viewContainer); root.setExpandRatio(viewContainer, 1.0f ); Navigator navigator = new Navigator(this , viewContainer); navigator.addProvider(viewProvider); } private Button createNavigationButton (String caption, final String viewName) { Button button = new Button(caption); button.addStyleName(ValoTheme.BUTTON_SMALL); button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName)); return button; } }
UIScopedViewとViewScopedViewを切り替えるButtonを設置。 ラムダ式を使って書くこともできる。
実行し2つのボタンを交互に押すとViewScopeの値が変更されるがUIScopeの値は変わらないことが確認できる。UIを再読込するとUIScopeの値も変更される。
その他 ほかはViewNameを指定しなかった場合に設定されるViewの命名規則が書いてあったりする。
明示的に名前をつけることを強く推奨しているが、VIEW名を指定しない場合はクラス名に基き以下の様に自動的に名前が割り当てられる。 HelloWorldView → hello-world ExampleView → example VisualEditor → visual-editor
まとめ あとはひたすらVaadinのドキュメント を読み込んで行く必要がある。
vaadinが用意しているテーマを使えば全くhtml, css, jsを書かなくても良い事がわかった。
例えばリンクが追加したければ以下のようにjavaを書くことで追加できるのが結構いい感じだなと思った。
Link link = new Link("Take me a away to a faraway land" , new ExternalResource("http://vaadin.com/" )); root.addComponent(link);
出処: https://vaadin.com/docs/-/part/framework/components/components-overview.html
htmlに対応するコンポーネントが用意されているので比較的簡単に画面が作れそうである。
db周りはspringですればいいのかな?ココらへんはまたの機会に。
終わり。