読者です 読者をやめる 読者になる 読者になる

m_shige1979のささやかな抵抗と欲望の日々

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

なんとなく作ったサイト

http://www.it-check-matome.info/


Github(注意すること)

https://github.com/mshige1979

Spring Bootでデータベースに接続

Spring Boot DB Java JPA

そろそろDB

Javaって他の言語より導入が面倒な部分が感じられるのでなかなか進まない

環境

Spring Boot 1.4
MySQL 5.x
MySQLvagrantに配置して接続してみる

DB設定

DDL作成
create table if not exists memo (
  id int not null auto_increment,
  name varchar(30) not null,
  memo varchar(128),
  create_at datetime not null default current_timestamp,
  update_at datetime not null default current_timestamp on update current_timestamp,
  primary key (id)
) engine = INNODB;
テストデータを作成
insert into `memo`(name, memo) values('test01', 'hogehoge01');
insert into `memo`(name, memo) values('test02', 'hogehoge02');
insert into `memo`(name, memo) values('test03', 'hogehoge03');
insert into `memo`(name, memo) values('test04', 'hogehoge04');
insert into `memo`(name, memo) values('test05', 'hogehoge05');
insert into `memo`(name, memo) values('test06', 'hogehoge06');
insert into `memo`(name, memo) values('test07', 'hogehoge07');
insert into `memo`(name, memo) values('test08', 'hogehoge08');
insert into `memo`(name, memo) values('test09', 'hogehoge09');
insert into `memo`(name, memo) values('test10', 'hogehoge10');

maven設定

pom.xml
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		
	</dependencies>

jpaMySQLの情報を追加

application.yml
server:
  port: 7777
spring:
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.33.10/myapp?useSSL=false
    username: app
    password: Password123@
  jpa:
    hibernate:
      show-sql: true
      ddl-auto: update
    database-platform: org.hibernate.dialect.MySQLDialect

MySQLの接続設定を追加

画面用(ホントはいらないかも…)

MemoForm.java
package com.example.beans;

import java.io.Serializable;
import java.sql.Timestamp;

public class MemoForm implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3570891756024535003L;

	private Integer id;
	private String name;
	private String memo;
	private Timestamp createAt;
	private Timestamp updateAt;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getMemo() {
		return memo;
	}

	public void setMemo(String memo) {
		this.memo = memo;
	}

	public Timestamp getCreateAt() {
		return createAt;
	}

	public void setCreateAt(Timestamp createAt) {
		this.createAt = createAt;
	}

	public Timestamp getUpdateAt() {
		return updateAt;
	}

	public void setUpdateAt(Timestamp updateAt) {
		this.updateAt = updateAt;
	}
	
}

エンティティ準備

Memo.java
package com.example.entities;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "memo")
public class Memo implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3570891756024535003L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	
	@Column(name="name")
	private String name;
	
	@Column(name="memo")
	private String memo;
	
	@Column(name="create_at")
	private Timestamp createAt;

	@Column(name="update_at")
	private Timestamp updateAt;
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getMemo() {
		return memo;
	}

	public void setMemo(String memo) {
		this.memo = memo;
	}

	public Timestamp getCreateAt() {
		return createAt;
	}

	public void setCreateAt(Timestamp createAt) {
		this.createAt = createAt;
	}

	public Timestamp getUpdateAt() {
		return updateAt;
	}

	public void setUpdateAt(Timestamp updateAt) {
		this.updateAt = updateAt;
	}
	
}

リポジトリ

MemoRepository.java
package com.example.repositories;

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.entities.Memo;

public interface MemoRepository extends JpaRepository<Memo, Long>{
	public Memo findById(Integer id);
}

サービス

MemoService.java
package com.example.services;

import java.sql.Timestamp;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.beans.MemoForm;
import com.example.entities.Memo;
import com.example.repositories.MemoRepository;

@Service
@Transactional
public class MemoService {
	@Autowired
	MemoRepository repository;
	
	/**
	 * 全件取得
	 * @return
	 */
	public List<Memo> getAllList() {
		return repository.findAll();
	}
	
	/**
	 * 1件取得
	 * @return
	 */
	public MemoForm getMemo(Integer id) {
		Memo newMemo = repository.findById(id);
		
		MemoForm form = new MemoForm();
		form.setId(newMemo.getId());
		form.setName(newMemo.getName());
		form.setMemo(newMemo.getMemo());
		form.setCreateAt(newMemo.getCreateAt());
		form.setUpdateAt(newMemo.getUpdateAt());
		
		return form;
	}
	
	/**
	 * 追加
	 * @param memo
	 * @return
	 */
	public Memo regist(MemoForm form) {
		
		// 新しく作成して値を設定
		Memo memo = new Memo();
		memo.setName(form.getName());
		memo.setMemo(form.getMemo());
		memo.setCreateAt(new Timestamp(System.currentTimeMillis()));
		memo.setUpdateAt(new Timestamp(System.currentTimeMillis()));
		
		// 登録
		return repository.save(memo);
	}
	
	/**
	 * 追加
	 * @param memo
	 * @return
	 */
	public Memo update(MemoForm form) {
		
		// 新しく作成して値を設定
		Memo memo = new Memo();
		memo.setId(form.getId());
		memo.setName(form.getName());
		memo.setMemo(form.getMemo());
		memo.setCreateAt(form.getCreateAt());
		memo.setUpdateAt(new Timestamp(System.currentTimeMillis()));
		
		// 更新
		return repository.save(memo);
	}
	
	/**
	 * 削除
	 * @param id
	 */
	public void remove(Integer id) {
		Memo memo = new Memo();
		memo.setId(id);
		repository.delete(memo);
	}
}

コントローラー

MemoController.java
package com.example.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.beans.MemoForm;
import com.example.entities.Memo;
import com.example.services.MemoService;

@Controller
@RequestMapping("memo")
public class MemoController {
	
	@Autowired
	private MemoService memoService;
	
	/**
	 * 一覧表示
	 * @return
	 */
	@RequestMapping(method = {RequestMethod.GET})
	public ModelAndView index() {
		
		// 一覧を取得
		List<Memo> list = memoService.getAllList();
		
		// Modelを生成
		ModelAndView mv = new ModelAndView();
		
		// 取得したデータを画面へ割当
		mv.addObject("list", list);
		
		// 使用するビューを指定
		mv.setViewName("memo/index");
		
		// view
		return mv;
	}
	
	/**
	 * 新規画面
	 * @return
	 */
	@RequestMapping(value = {"new"}, method = {RequestMethod.GET})
	public ModelAndView _new(@ModelAttribute MemoForm form) {
		
		// Modelを生成
		ModelAndView mv = new ModelAndView();
				
		// 使用するビューを指定
		mv.setViewName("memo/new");
		
		// formを設定する
		mv.addObject("form", form);
		
		// view
		return mv;
	}
	
	/**
	 * 登録処理
	 * @return
	 */
	@RequestMapping(value = {"regist"}, method = {RequestMethod.POST})
	public String regist(@ModelAttribute MemoForm form) {
		
		// 追加処理
		memoService.regist(form);
		
		// view
		return "redirect:/memo";
	}
	
	/**
	 * 編集画面
	 * @param id
	 * @return
	 */
	@RequestMapping(value = {"edit/{id}"}, method = {RequestMethod.GET})
	public ModelAndView edit(@PathVariable("id") String id) {
		
		MemoForm form = memoService.getMemo(Integer.parseInt(id));
		
		// Modelを生成
		ModelAndView mv = new ModelAndView();
						
		// 使用するビューを指定
		mv.setViewName("memo/edit");
			
		// formを設定する
		mv.addObject("form", form);
				
		// view
		return mv;
	}
	
	/**
	 * 更新処理
	 * @return
	 */
	@RequestMapping(value = {"update"}, method = {RequestMethod.POST})
	public String update(@ModelAttribute MemoForm form) {
		
		// 更新処理
		memoService.update(form);
		
		// view
		return "redirect:/memo";
	}
	
	/**
	 * 削除実施
	 * @param id
	 * @return
	 */
	@RequestMapping(value = {"remove/{id}"}, method = {RequestMethod.GET})
	public String remove(@PathVariable("id") String id) {
		
		// 削除実行
		memoService.remove(Integer.parseInt(id));
		
		// 一覧へリダイレクトする
		return "redirect:/memo";
	}
	
}

ビュー

memo/index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Memo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Memo Sample</h1>
	<div>
		<a href="/memo/new">new</a>
    	<table>
    		<tbody th:if="${list} != null">
    			<tr th:each="memo: ${list}">
    				<td th:text="${memo.id}"><br /></td>
    				<td th:text="${memo.name}"><br /></td>
    				<td th:text="${memo.memo}"><br /></td>
    				<td th:text="${memo.createAt}"><br /></td>
    				<td th:text="${memo.updateAt}"><br /></td>
    				<td>
    					<a th:href="@{/memo/edit/{id}(id=${memo.id})}">edit</a>
    				</td>
    				<td>
    					<a th:href="@{/memo/remove/{id}(id=${memo.id})}">remove</a>
    				</td>
    			</tr>
    		</tbody>
    	</table>
	</div>
</body>
</html>
memo/new.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Memo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Memo Sample</h1>
	<div>
    	<form th:action="@{/memo/regist}" method="post">
    		<table>
    			<tr>
    				<th>name</th>
    				<td>
    					<input type="text" name="name" />
    				</td>
    			</tr>
    			<tr>
    				<th>memo</th>
    				<td>
    					<input type="text" name="memo" />
    				</td>
    			</tr>
    		</table>
    		<input type="submit" value="登録する" />
    	</form>
	</div>
</body>
</html>
memo/edit.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Memo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Memo Sample</h1>
	<div>
    	<form th:action="@{/memo/update}"  method="post">
    		<input type="hidden" name="id" th:field="${form.id}" />
    		<input type="hidden" name="createAt" th:field="${form.createAt}" />
    		<table>
    			<tr>
    				<th>name</th>
    				<td>
    					<input type="text" name="name" th:field="${form.name}" />
    				</td>
    			</tr>
    			<tr>
    				<th>memo</th>
    				<td>
    					<input type="text" name="memo" th:field="${form.memo}" />
    				</td>
    			</tr>
    		</table>
    		<input type="submit" value="更新する" />
    	</form>
	</div>
</body>
</html>

実行

所感

さわりさわりなのでまだ違和感がある。
なんとかここまでこぎつけた。まだ、認証とかバリデーションとかあるのでそのあたりも調べないといけない
結構やること多いです(´・ω・`)

vagrant上に Redisをインストールする

Redis NoSQL DB

Redis

キーバリュー型のNoSQLデータベースらしいMongoDBとかちょっと違う感じのやつ

環境

vagrant上のCentOS7

インストール

epelインストール
sudo yum -y install epel-release
redisインストール
sudo yum -y install redis
バージョン確認
$ redis-cli -v
redis-cli 2.8.19
$
自動起動して、起動
sudo systemctl enable redis
sudo systemctl start redis

起動

$ redis-cli
127.0.0.1:6379> set test hoge1
OK
127.0.0.1:6379> get test
"hoge1"
127.0.0.1:6379>
127.0.0.1:6379> set test2 aaaa
OK
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "test2"
2) "test"
127.0.0.1:6379>
127.0.0.1:6379> exit
$

外部から接続

ホストへredisをインストール
brew install redis
接続元編集

/etc/redis.conf

#bind 127.0.0.1
bind 0.0.0.0

※bindを変更する

接続元のredisを再起動
sudo systemctl restart redis
ホストより接続
$ redis-cli -h 192.168.33.10
192.168.33.10:6379> keys
(error) ERR wrong number of arguments for 'keys' command
192.168.33.10:6379> keys *
1) "test2"
2) "test"
192.168.33.10:6379>
192.168.33.10:6379> get test
"hoge1"
192.168.33.10:6379>
192.168.33.10:6379> get test2
"aaaa"
192.168.33.10:6379> exit
$

所感

複雑なデータを管理するのには向かない感じだけどちょっとだけ残しておきたいデータを管理するのには役に立ちそう。
Spring Bootでセッション管理するのにつかうような記事が多かったのでこれを使ってみる。

MySQL5.7をvagrant上のCentOS7へインストール

MySQL yum DB

Mac上にはDBなどはインストールしたくない

perlとかの言語系はともかく、DBはクライアントだけならいけど本体はいらん

インストールするもの

MySQL5.7.x

インストールする場所

mac上のvagrantのCentOS7.x

インストール

sudo yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
sudo yum -y install mysql-community-server

自動起動の設定して、起動する

sudo systemctl enable mysqld.service
sudo systemctl start mysqld.service

初期パスワードを確認

sudo cat /var/log/mysqld.log
----
2016-11-25T20:29:28.134584Z 1 [Note] A temporary password is generated for root@localhost: eudf/s_ak2oE
----

ほう、/var/log/mysqld.logに出力するようです。

仮パスワードでアクセスしてrootパスワードを変更

mysql -uroot -p
----
set password for root@localhost=password('Password123@');
----

※パスワードの制限が結構厳しい

新しいユーザーを作成

mysql -uroot -p
----
GRANT ALL ON *.* TO 'app'@'%' IDENTIFIED BY 'Password123@' WITH GRANT OPTION;
FLUSH PRIVILEGES;
----

新しいデータベースを作成

mysql -uroot -p
----
create database myapp;
----

macからクライアントでアクセス

クライアントのインストール
brew install mysql --client-only
アクセス
mysql -uapp -h 192.168.33.10 -p
----
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use myapp;
Database changed
mysql>
----

できました(^^)

所感

機能が新しくなっていくにつれ対応が必要なのは仕方がない。
最新の機能や技術は知っておかないとあとで苦労することになるので…
きちんとCentOS7のことも調べておかないと…

Spring bootでHttpSessionを使用する

Spring Boot session

セッションを使用する

データが複数画面に跨ったり一定期間データを保持する必要があるデータの管理をすることがあるので…

イメージ

f:id:m_shige1979:20161126041412p:plain
うん、適当だねw

やること

  • コントローラーでセッションを使用する
  • データを渡すフォーム系のクラスをシリアライズ化する

実装

src/main/java/HelloController.java
package com.example;

import java.util.Date;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.beans.TestForm;

@Controller
public class HelloController {
	
	@Autowired
	HttpSession session;
	
	@RequestMapping(value = {"/"}, method = {RequestMethod.GET})
	public ModelAndView index(@ModelAttribute TestForm form) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("index");
		
		// 日時を取得、設定
		mv.addObject("now", new Date().toString());
		
		// modelに設定して画面に表示するようにする
		mv.addObject("form", form);
		
		// 返却
		return mv;
	}
	
	// POST用のパラメータを受け取る
	@RequestMapping(value = {"/formPost"}, method = {RequestMethod.POST})
	public String postTest1(
			@ModelAttribute TestForm form) {
		
		// セッションへ保存
		session.setAttribute("form", form);
		
		// リダイレクト
		return "redirect:/formPostView";
	}
	
	// GET用のパラメータを受け取る
	@RequestMapping(value = {"/formPostView"}, method = {RequestMethod.GET})
	public ModelAndView getTest1() {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("test1/post");
		
		// セッションを取得
		TestForm form = (TestForm) session.getAttribute("form");
		if(null != form){
			// セッションよりデータを取得して設定
			mv.addObject("form", form);
		}
		
		// セッションクリア
		session.invalidate();
		
		// 返却
		return mv;
	}
	
}

※最後にセッションをクリアします

src/main/java/TestForm.java
package com.example.beans;

import java.io.Serializable;

public class TestForm implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 4674112863194397526L;
	private String name;
	private String age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}
}
src/main/resources/templates/test1/post.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Post Data
	</div>
	<br />
	<form method="post" action="formPost">
		<span>name: </span>
		<span th:if="${form} != null" th:text="${form.name}"></span>
		<br />
		<span>age: </span>
		<span th:if="${form} != null" th:text="${form.age}"></span>
		<br />
	</form>
	<a href="/">back</a>
</body>
</html>

実行

f:id:m_shige1979:20161126044245p:plain

f:id:m_shige1979:20161126044258p:plain

リロードしたあと
f:id:m_shige1979:20161126044326p:plain

所感

セッションのデータの扱いはそこまで複雑ではないかと期待する。
Javaになるとロードバランサとか絡んでいくのでセッションの関与もちょっとややこしいことになりそうだけど
扱い自体はそこまで手間をかけたくないので…

Spring Bootでリクエスト時の受け取るパラメータをクラスにする

Java Spring Boot 備忘録

リクエストパラメータを1つずつ書くのはちょっと手間がかかる

もう少し楽したい(^^)

こんな感じのクラスを用意

TestForm.java
package com.example.beans;

public class TestForm {
	
	private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

※lombokを使用したかったけどわからなくなるのでやめた

コントローラー

HelloController.java
package com.example;

import java.util.Date;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.example.beans.TestForm;

@Controller
public class HelloController {
	
	@RequestMapping(value = {"/"}, method = {RequestMethod.GET})
	public ModelAndView index(@ModelAttribute TestForm form) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("index");
		
		// 日時を取得、設定
		mv.addObject("now", new Date().toString());
		
		// modelに設定して画面に表示するようにする
		mv.addObject("form", form);
		
		// 返却
		return mv;
	}
	
	// POST用のパラメータを受け取る
	@RequestMapping(value = {"/formPost"}, method = {RequestMethod.POST})
	public ModelAndView postTest1(
			@ModelAttribute TestForm form) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("test1/post");
		
		// modelに設定して画面に表示するようにする
		mv.addObject("form", form);
		
		// 返却
		return mv;
	}
	
	// GET用のパラメータを受け取る
	@RequestMapping(value = {"/formPost"}, method = {RequestMethod.GET})
	public ModelAndView getTest1(
			@ModelAttribute TestForm form) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("test1/post");
		
		// modelに設定して画面に表示するようにする
		mv.addObject("form", form);
		
		// 返却
		return mv;
	}
	
}

※ModelAttributeを使用するように変更

画面

index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Spring Sample Test
	</div>
	<p>Now <span th:text="${now}"></span></p>
	<br />
	<form method="post" action="formPost">
		<span>name: </span>
		<input type="text" name="name" th:field="${form.name}" />
		<br />
		<span>age: </span>
		<input type="text" name="age" th:field="${form.age}" />
		<br />
		<input type="submit" value="send" />
	</form>
</body>
</html>
post.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Post Data
	</div>
	<br />
	<form method="post" action="formPost">
		<span>name: </span>
		<span th:text="${form.name}"></span>
		<br />
		<span>age: </span>
		<span th:text="${form.age}"></span>
		<br />
	</form>
</body>
</html>

所感

単純な受取が少しだけ楽になった感じ…
システムが複雑になるにつれて便利になっていくと思うので忘れないようにしたい。

Spring Bootで画面へ設定した入力を他の画面へ渡す

Java Spring Boot 備忘録

一般的画面遷移

f:id:m_shige1979:20161123120710p:plain

入力→確認

入力画面を設定して、確認画面で内容を表示する

画面構成

/の場合のページ
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Spring Sample Test
	</div>
	<p>Now <span th:text="${now}"></span></p>
	<br />
	<form method="post" action="formPost">
		<span>name: </span>
		<input type="text" name="name" value="" />
		<br />
		<span>age: </span>
		<input type="text" name="age" value="" />
		<br />
		<input type="submit" value="send" />
	</form>
</body>
</html>
/formPostの場合のページ
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Post Data
	</div>
	<br />
	<form method="post" action="formPost">
		<span>name: </span>
		<span th:text="${name}"></span>
		<br />
		<span>age: </span>
		<span th:text="${age}"></span>
		<br />
	</form>
</body>
</html>

コントローラー実装

package com.example;

import java.util.Date;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController {
	
	@RequestMapping(value = {"/"}, method = {RequestMethod.GET})
	public ModelAndView index() {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("index");
		
		// 日時を取得、設定
		mv.addObject("now", new Date().toString());
		
		// 返却
		return mv;
	}
	
	// POST用のパラメータを受け取る
	@RequestMapping(value = {"/formPost"}, method = {RequestMethod.POST})
	public ModelAndView postTest1(
			@RequestParam(value="name", required = true) String name,
			@RequestParam(value="age", required = true) String age) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("test1/post");
		
		// modelに設定して画面に表示するようにする
		mv.addObject("name", name);
		mv.addObject("age", age);
		
		// 返却
		return mv;
	}
	
	// GET用のパラメータを受け取る
	@RequestMapping(value = {"/formPost"}, method = {RequestMethod.GET})
	public ModelAndView getTest1(
			@RequestParam(value="name", required = true) String name,
			@RequestParam(value="age", required = true) String age) {
		
		// 生成
		ModelAndView mv = new ModelAndView();
		
		// テンプレートを指定
		mv.setViewName("test1/post");
		
		// modelに設定して画面に表示するようにする
		mv.addObject("name", name);
		mv.addObject("age", age);
		
		// 返却
		return mv;
	}
	
}

実行

f:id:m_shige1979:20161123130602p:plain

f:id:m_shige1979:20161123130617p:plain

GETパラメータ指定でも動く

f:id:m_shige1979:20161123130854p:plain

参考

Spring Boot触ってみる その2 ーController,テンプレートエンジン(Thymeleaf)ー - endokのブログ
Spring MVC 4.0 No. 005 GETパラメータを受け取る - コンピュータクワガタ

うーん、ModelとModelAndViewの使い方はなんとなくわかったけど使い分けはわからない…
とりあえず、ModelAndViewを使っていこう…

所感

このまま場合ではパラメータが増えたときの対応がややこしくなるのでクラスを渡してできるかを調べる。
PHPでやっていたときは配列で渡していたけどJavaはクラスを使ってなんとかする感じのはずなのでそれで対応する。

JavaのSpring bootでthymeleafを使用する

Java Spring Boot thymeleaf

直接HTMLを記載するわけにはいかない

いろいろなフレームワークではテンプレートを使用する

環境

Mac mini
Spring Boot 1.4.x
Java 8

Maven設定

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

※「spring-boot-starter-thymeleaf」を追加

ソース設定

HelloController.java
package com.example;

import java.util.Date;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	
	@RequestMapping("/")
	public String index(Model model) {
		// 日時を取得、設定
		model.addAttribute("now", new Date().toString());
		// テンプレートを指定
		return "index";
	}
	
	@RequestMapping("/test1")
	public String test1Index(Model model) {
		// テンプレートを指定
		return "test1/index";
	}
	
}

※@RestControllerではテンプレートを使用しないので@Controllerに変更する
※アクションメソッドにModelを指定することで画面へ反映するオブジェクトを設定できる
※returnにはテンプレートのパスを設定する

テンプレート設定

src/main/resources/templates/index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample</h1>
	<div>
    	Spring Sample Test
	</div>
	<p>Now <span th:text="${now}"></span></p>
	<p>
		<a href="test1/">test1</a>
	</p>
</body>
</html>
src/main/resources/templates/test1/index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Sample Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Spring Sample Test1/index</h1>
	<div>
    	Spring Sample Test Test1/index
	</div>
</body>
</html>

結果

f:id:m_shige1979:20161122074419p:plain
f:id:m_shige1979:20161122074427p:plain

所感

WebアプリケーションフレームワークではHTMLをたくさん書くことになるのでテンプレートを使用するのは必須となる。
MVCとして使うことになると思うのでDBを実際に使用してTODOアプリもどきを作成できるように考えておく。