LoginSignup
5
4

More than 5 years have passed since last update.

Spring Boot + Vaadin (Vaadin4Spring)

Last updated at Posted at 2015-01-29

はじめに

Spring Boot + Apache Wicket はできてきた感があるので、Vaadinにも挑戦してみる。

Vaadin4Spring

Spring Boot + Vaddin の先駆として、peholmst/vaadin4springがある。まずはこれを使わせてもらう。

README.mdの通りに、まず、SPRING INITIALIZRで、Webプロジェクトを作成する。

次に、pom.xmlのdependenciesspring-boot-vaadin, vaadin-themes, vaadin-client-compiledを登録する

<!-- Vaadin4Spring -->
<!-- 記事の執筆時点でspring-boot-vaadin 0.0.3.1のvaadinは7.3.6なので、後ほど実行時にはコンソールにアラートが発生する。バージョンを合わせたいときは調整する -->
<dependency>
  <groupId>org.vaadin.spring</groupId>
  <artifactId>spring-boot-vaadin</artifactId>
  <version>0.0.3.1</version>
</dependency>
<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-themes</artifactId>
  <version>7.3.9</version>
</dependency>
<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-client-compiled</artifactId>
  <version>7.3.9</version>
</dependency>

ログイン画面を作ってみる

VaadinのWikiにCreating a simple login viewという記事があるので、これを参考にし、簡単なログイン画面を作ってみる。

画面を制御するためのMainUIクラス、ログイン画面を表示するLoginViewクラス、ログイン後の画面を表示するLoginedViewクラスの3種類を作成する。

MainUI

以下、WikiのSimpleLoginUIを引用し改変している。

package com.example.ui;

import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.VaadinUI;
import org.vaadin.spring.navigator.SpringViewProvider;

import com.vaadin.annotations.Theme;
import com.vaadin.navigator.Navigator;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;

@Theme("valo")
@VaadinUI
public class MainUI extends UI {

  @Autowired
  private SpringViewProvider viewProvider;

  @Override
  protected void init(VaadinRequest request) {
    Navigator navigator = new Navigator(this, this);
    navigator.addProvider(viewProvider);
    navigator.addViewChangeListener(new ViewChangeListener() {

      @Override
      public boolean beforeViewChange(ViewChangeEvent event) {

        boolean isLoggedIn = getSession().getAttribute("user") != null;
        boolean isLoginView = event.getNewView() instanceof LoginView;

        if (!isLoggedIn && !isLoginView) {
          getNavigator().navigateTo(LoginView.NAME);
          return false;
        } else if (isLoggedIn && isLoginView) {
          return false;
        }
        return true;
      }

      @Override
      public void afterViewChange(ViewChangeEvent event) {

      }
    });
    setNavigator(navigator);
  }
}

@VaadinUIで、URLでアクセス可能なUIであることを設定。Vaadinではページ遷移はNavigatorで行うが、これをアノテーションで管理するためのSpringViewProviderをInjectする。

@Theme("valo")で、Vaadinの綺麗なCSSテーマであるValoを利用してくれる。

LoginView

以下、WikiのSimpleLoginViewを引用し改変している。

package com.example.ui;

import org.vaadin.spring.UIScope;
import org.vaadin.spring.navigator.VaadinView;

import com.vaadin.annotations.Theme;
import com.vaadin.data.validator.AbstractValidator;
import com.vaadin.data.validator.EmailValidator;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;

@UIScope
@VaadinView(name = LoginView.NAME)
public class LoginView extends CustomComponent implements View {

  public static final String NAME = "";

  private final TextField user;

  private final PasswordField password;

  private final Button loginButton;

  public LoginView() {
    setSizeFull();

    user = new TextField("ユーザー名:");
    user.setWidth("300px");
    user.setRequired(true);
    user.setInputPrompt("例:user@example.com");
    user.addValidator(new EmailValidator("ユーザ名かパスワードが不正です"));
    user.setInvalidAllowed(false);

    password = new PasswordField("パスワード:");
    password.setWidth("300px");
    password.addValidator(new PasswordValidator());
    password.setRequired(true);
    password.setValue("");
    password.setNullRepresentation("");

    loginButton = new Button("ログイン", e -> {
      if (!user.isValid() || !password.isValid()) {
        return;
      }

      String username = user.getValue();
      String password = this.password.getValue();

      boolean isValid = username.equals("test@test.com")
                        && password.equals("passw0rd");

      if (isValid) {
        getSession().setAttribute("user", username);
        getUI().getNavigator().navigateTo(LoginedView.NAME);
      } else {
        this.password.setValue(null);
        this.password.focus();
      }
    });

    VerticalLayout fields = new VerticalLayout(user, password, loginButton);
    fields.setCaption("ログインしてください (test@test.com/passw0rd)");
    fields.setSpacing(true);
    fields.setMargin(new MarginInfo(true, true, true, false));
    fields.setSizeUndefined();

    VerticalLayout viewLayout = new VerticalLayout(fields);
    viewLayout.setSizeFull();
    viewLayout.setComponentAlignment(fields, Alignment.MIDDLE_CENTER);
    viewLayout.setStyleName(Reindeer.LAYOUT_BLUE);
    setCompositionRoot(viewLayout);
  }

  @Override
  public void enter(ViewChangeEvent event) {
    user.focus();
  }

  private static final class PasswordValidator extends AbstractValidator<String> {

    public PasswordValidator() {
      super("ユーザ名かパスワードが不正です");
    }

    @Override
    protected boolean isValidValue(String value) {
      return value != null ? value.length() >= 8 && value.matches(".*\\d.*") : false;
    }

    @Override
    public Class<String> getType() {
      return String.class;
    }
  }

}

ちょっとバリデーションなどが設定されていてごちゃごちゃしてる感があるけど、原則的にはTextFieldButtonのコンポーネントに設定を付け加えてあるだけ。

@UIScopeでスコープを設定する。@VaadinViewは、ページとなるViewにマッピングされる名称。(Vaadin的に、初期ページは空文字でマッピングしないといけない...?ちょっと自信ない)。

ボタンのリスナーにラムダ式を使えるのがすっきりしてて素敵。

LoginedView

以下、WikiのSimpleLoginMainViewを引用し改変している。

package com.example.ui;

import org.vaadin.spring.UIScope;
import org.vaadin.spring.navigator.VaadinView;

import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;

@UIScope
@VaadinView(name = LoginedView.NAME)
public class LoginedView extends CustomComponent implements View {

  public static final String NAME = "LoginedView";

  private Label text = new Label();

  private Button logout = new Button("ログアウト", e -> {
    getSession().setAttribute("user", null);
    getUI().getNavigator().navigateTo(NAME);
  });

  public LoginedView() {
    setCompositionRoot(new CssLayout(text, logout));
  }

  @Override
  public void enter(ViewChangeEvent event) {
    String username = String.valueOf(getSession().getAttribute("user"));
    text.setValue("ようこそ、 " + username);
  }
}

実行結果


Spring_Boot+Vaadin_01a.png


Spring_Boot+Vaadin_01b.png


Vaadinを使うと(Layoutの使い方に慣れが必要そうだけど)HTMLを書かずにWebシステムを構築していける。Spring4Vaadinを使えば、Navigatorなどの面倒になりがちな設定もアノテーションを拾って自動設定してくれる。慣れてくると爽快に開発できそうだなあ。

なお、ここまでのソースコードはgishi-yama/springboot-vaadin-sample/tree/61086783ecにpushしてある。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4