m_shige1979のときどきITブログ

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

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

doma2を使用したin句の条件設定

完全一致はあるけど

他の方法ってなかなか見つからないです

IN句による条件指定

select
	*
from
	keiyaku
where 
	name in ('tanaka', 'inoue')

こんなやつ

Dao

KeiyakuDao.java
package com.example.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;

import com.example.config.AppConfig;
import com.example.entity.Keiyaku;
import com.example.entity.KeiyakuItem;

@Dao(config = AppConfig.class)
public interface KeiyakuDao {
	
	@Select
	List<Keiyaku> findNamesSearchAll(List<String> names);
	
}

※引数にList形式で設定する

SQL

findNamesSearchAll.sql
select
	*
from
	keiyaku
where
	where name in /* names */('aaa', 'bbb', 'ccc')

※inを指定するが別に特別な記載はしない

実行

Sample01.java
package com.example;

import java.util.Arrays;
import java.util.List;

import org.seasar.doma.jdbc.tx.TransactionManager;

import com.example.config.AppConfig;
import com.example.dao.KeiyakuDao;
import com.example.dao.KeiyakuDaoImpl;
import com.example.entity.Keiyaku;
import com.example.entity.KeiyakuItem;

public class Sample01 {

	public static void main(String[] args) {
		
		TransactionManager tm = AppConfig.singleton().getTransactionManager();
		tm.required(new Runnable(){

			@Override
			public void run() {
				KeiyakuDao dao = new KeiyakuDaoImpl();
				
				List<Keiyaku> list;
				list = dao.findNamesSearchAll(Arrays.asList("tanaka", "inoue"));	
			}		
		});
	}
}

1 04, 2017 11:35:44 午前 org.seasar.doma.jdbc.tx.LocalTransaction begin
情報: [DOMA2063] ローカルトランザクション[1190654826]を開始しました。
1 04, 2017 11:35:44 午前 com.example.dao.KeiyakuDaoImpl findNamesSearchAll
情報: [DOMA2220] ENTER  : クラス=[com.example.dao.KeiyakuDaoImpl], メソッド=[findNamesSearchAll]
1 04, 2017 11:35:44 午前 com.example.dao.KeiyakuDaoImpl findNamesSearchAll
情報: [DOMA2076] SQLログ : SQLファイル=[META-INF/com/example/dao/KeiyakuDao/findNamesSearchAll.sql],
select
	*
from
	keiyaku
where name in ('tanaka', 'inoue')
1 04, 2017 11:35:44 午前 com.example.dao.KeiyakuDaoImpl findNamesSearchAll
情報: [DOMA2221] EXIT   : クラス=[com.example.dao.KeiyakuDaoImpl], メソッド=[findNamesSearchAll]
1 04, 2017 11:35:44 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2067] ローカルトランザクション[1190654826]をコミットしました。
1 04, 2017 11:35:44 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2064] ローカルトランザクション[1190654826]を終了しました。


まあ、こんな感じですかね…

doma2で部分一致検索を行う

Doma2で部分一致検索する際

%とかを任意で設定するのは止めたい

組み込み関数を使う

名前 関数名
前方一致 prefix where name like /* @prefix(name) */'smith'
後方一致 suffix where name like /* @suffix(name) */'smith'
前方後方一致 infix where name like /* @infix(name) */'smith'

Dao

KeiyakuDao.java
package com.example.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;

import com.example.config.AppConfig;
import com.example.entity.Keiyaku;
import com.example.entity.KeiyakuItem;

@Dao(config = AppConfig.class)
public interface KeiyakuDao {
	
	@Select
	List<KeiyakuItem> findKeiyakuMeisaiAll();
	
	@Select
	List<Keiyaku> findNameStartSearchAll(String name);
	
	@Select
	List<Keiyaku> findNameEndSearchAll(String name);
	
	@Select
	List<Keiyaku> findNameContainSearchAll(String name);
	
}

SQL

findNameStartSearchAll.sql
select
	*
from
	keiyaku
where
	where name like /* @prefix(name) */'smith'
findNameEndSearchAll.sql
select
	*
from
	keiyaku
where
	where name like /* @suffix(name) */'smith'
findNameContainSearchAll.sql
select
	*
from
	keiyaku
where
	where name like /* @infix(name) */'smith'

実行結果

実行時のSQLを記載
select
	*
from
	keiyaku
where name like 'hoge%'

select
	*
from
	keiyaku
where name like '%hoge'

select
	*
from
	keiyaku
where name like '%hoge%'

わかったこと

  • 部分一致検索にはdoma2の組み込み関数を使用することで自動的に%などを設定してくれる

doma2で複数のテーブルを結合した結果を取得する

Javaオブジェクト指向はなんか難しく感じる

永続化とかなんかもう少しわかりやすい表現ないかな…

複数のテーブルを連結したい

1つのテーブルの取得はできるけど複数テーブルの場合はどうするか確認
コレクト検索とかストリーム検索とかわからん

DDL

drop table if exists item;
create table if not exists item (
	id         int not null auto_increment,
	name       varchar(255) not null,
	price      int not null,
	create_at  datetime,
	update_at  datetime,
	primary key(id)
);

drop table if exists keiyaku;
create table if not exists keiyaku (
	id         int not null auto_increment,
	name       varchar(255) not null,
	item_id    int not null,
	item_count int not null,
	create_at  datetime,
	update_at  datetime,
	primary key(id)
);

insert into item(id, name, price, create_at, update_at) values(1, 'apple' , 120, current_timestamp, current_timestamp);
insert into item(id, name, price, create_at, update_at) values(2, 'orange', 150, current_timestamp, current_timestamp);
insert into item(id, name, price, create_at, update_at) values(3, 'grape' , 200, current_timestamp, current_timestamp);

insert into keiyaku(name, item_id, item_count, create_at, update_at) values('tanaka', 1, 10, current_timestamp, current_timestamp);
insert into keiyaku(name, item_id, item_count, create_at, update_at) values('satou', 2, 30, current_timestamp, current_timestamp);
insert into keiyaku(name, item_id, item_count, create_at, update_at) values('inoue', 3, 4, current_timestamp, current_timestamp);
insert into keiyaku(name, item_id, item_count, create_at, update_at) values('iizuka', 4, 21, current_timestamp, current_timestamp);

接続情報

AppConfig.java
package com.example.config;

import javax.sql.DataSource;

import org.seasar.doma.SingletonConfig;
import org.seasar.doma.jdbc.Config;
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.dialect.MysqlDialect;
import org.seasar.doma.jdbc.tx.LocalTransactionDataSource;
import org.seasar.doma.jdbc.tx.LocalTransactionManager;
import org.seasar.doma.jdbc.tx.TransactionManager;

@SingletonConfig
public class AppConfig implements Config {
	
	private static final AppConfig INSTANCE = new AppConfig();

    private final Dialect dialect;
    private final LocalTransactionDataSource dataSource;
    private final TransactionManager transactionManager;

    private AppConfig() {
        dialect = new MysqlDialect();
        dataSource = new LocalTransactionDataSource("jdbc:mysql://192.168.33.10:3306/myapp?useSSL=false", "app", "Password123@");
        transactionManager = new LocalTransactionManager(dataSource.getLocalTransaction(getJdbcLogger()));
    }
	
	@Override
	public DataSource getDataSource() {
		return dataSource;
	}

	@Override
	public Dialect getDialect() {
		return dialect;
	}
	
	@Override
    public TransactionManager getTransactionManager() {
        return transactionManager;
    }

    public static AppConfig singleton() {
        return INSTANCE;
    }

}

エンティティ

Item.java
package com.example.entity;

import java.time.LocalDateTime;

import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;
import org.seasar.doma.Table;

@Entity
@Table(name = "item")
public class Item {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "price")
	private Integer price;
	
	@Column(name = "create_at")
	private LocalDateTime createAt;
	
	@Column(name = "update_at")
	private LocalDateTime 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 Integer getPrice() {
		return price;
	}

	public void setPrice(Integer price) {
		this.price = price;
	}

	public LocalDateTime getCreateAt() {
		return createAt;
	}

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

	public LocalDateTime getUpdateAt() {
		return updateAt;
	}

	public void setUpdateAt(LocalDateTime updateAt) {
		this.updateAt = updateAt;
	}
	
	
	
}
Keiyaku.java
package com.example.entity;

import java.time.LocalDateTime;

import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;
import org.seasar.doma.Table;

@Entity
@Table(name = "keiyaku")
public class Keiyaku {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "item_id")
	private Integer itemId;
	
	@Column(name = "item_count")
	private Integer itemCount;
	
	@Column(name = "create_at")
	private LocalDateTime createAt;
	
	@Column(name = "update_at")
	private LocalDateTime 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 Integer getItemId() {
		return itemId;
	}

	public void setItemId(Integer itemId) {
		this.itemId = itemId;
	}
	
	public Integer getItemCount() {
		return itemCount;
	}

	public void setItemCount(Integer itemCount) {
		this.itemCount = itemCount;
	}

	public LocalDateTime getCreateAt() {
		return createAt;
	}

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

	public LocalDateTime getUpdateAt() {
		return updateAt;
	}

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

Dao

KeiyakuDao.java
package com.example.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;

import com.example.config.AppConfig;
import com.example.entity.KeiyakuItem;

@Dao(config = AppConfig.class)
public interface KeiyakuDao {
	
	@Select
	List<KeiyakuItem> findKeiyakuMeisaiAll();
	
}

SQL

findKeiyakuMeisaiAll.sql
select
	keiyaku.id as id
	, keiyaku.name as name
	, keiyaku.item_id as item_id
	, item.name as item_name
	, item.price as item_price
	, keiyaku.item_count as item_count
from
	keiyaku
	left outer join item on
		item.id = keiyaku.item_id

1つのSQLに複数のテーブルを設定すること自体は可能だが、設定するものが必要なので別途エンティティを追加する

カスタムエンティティ

KeiyakuItem.java
package com.example.entity;

import org.seasar.doma.Column;
import org.seasar.doma.Entity;

@Entity
public class KeiyakuItem {
	
	@Column(name = "id")
	private Integer id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "item_id")
	private Integer itemId;
	
	@Column(name = "item_name")
	private String itemName;
	
	@Column(name = "item_price")
	private Integer itemPrice;
	
	@Column(name = "item_count")
	private Integer itemCount;
	
	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 Integer getItemId() {
		return itemId;
	}
	public void setItemId(Integer itemId) {
		this.itemId = itemId;
	}
	public String getItemName() {
		return itemName;
	}
	public void setItemName(String itemName) {
		this.itemName = itemName;
	}
	public Integer getItemPrice() {
		return itemPrice;
	}
	public void setItemPrice(Integer itemPrice) {
		this.itemPrice = itemPrice;
	}
	public Integer getItemCount() {
		return itemCount;
	}
	public void setItemCount(Integer itemCount) {
		this.itemCount = itemCount;
	}
	
	public String toString() {
		String res = "";
		
		res += this.getId() + " ";
		res += this.getName() + " ";
		res += this.getItemId() + " ";
		res += this.getItemName() + " ";
		res += this.getItemPrice() + " ";
		res += this.getItemCount() + " ";
		
		return res;
	}
	
}

これでSQLの結果フィールドに値が設定される

実行プログラム

Sample01.java
package com.example;

import java.util.List;

import org.seasar.doma.jdbc.tx.TransactionManager;

import com.example.config.AppConfig;
import com.example.dao.KeiyakuDao;
import com.example.dao.KeiyakuDaoImpl;
import com.example.entity.KeiyakuItem;

public class Sample01 {

	public static void main(String[] args) {
		
		TransactionManager tm = AppConfig.singleton().getTransactionManager();
		tm.required(new Runnable(){

			@Override
			public void run() {
				KeiyakuDao dao = new KeiyakuDaoImpl();
				
				List<KeiyakuItem> list = dao.findKeiyakuMeisaiAll();
				for(KeiyakuItem entity : list) {
					System.out.println(entity.toString());
				}
			}
			
		});
		
		

	}

}

1 04, 2017 10:06:26 午前 org.seasar.doma.jdbc.tx.LocalTransaction begin
情報: [DOMA2063] ローカルトランザクション[1190654826]を開始しました。
1 04, 2017 10:06:26 午前 com.example.dao.KeiyakuDaoImpl findKeiyakuMeisaiAll
情報: [DOMA2220] ENTER  : クラス=[com.example.dao.KeiyakuDaoImpl], メソッド=[findKeiyakuMeisaiAll]
1 04, 2017 10:06:27 午前 com.example.dao.KeiyakuDaoImpl findKeiyakuMeisaiAll
情報: [DOMA2076] SQLログ : SQLファイル=[META-INF/com/example/dao/KeiyakuDao/findKeiyakuMeisaiAll.sql],
select
	keiyaku.id as id
	, keiyaku.name as name
	, keiyaku.item_id as item_id
	, item.name as item_name
	, item.price as item_price
	, keiyaku.item_count as item_count
from
	keiyaku
	left outer join item on
		item.id = keiyaku.item_id
1 04, 2017 10:06:27 午前 com.example.dao.KeiyakuDaoImpl findKeiyakuMeisaiAll
情報: [DOMA2221] EXIT   : クラス=[com.example.dao.KeiyakuDaoImpl], メソッド=[findKeiyakuMeisaiAll]
1 tanaka 1 apple 120 10 
2 satou 2 orange 150 30 
3 inoue 3 grape 200 4 
4 inoue 4 null null 21 
1 04, 2017 10:06:27 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2067] ローカルトランザクション[1190654826]をコミットしました。
1 04, 2017 10:06:27 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2064] ローカルトランザクション[1190654826]を終了しました。

関連がないところはnullが設定される。

わかったこと

おわり

doma2で抽出件数を取得

マニュアルみたけど

CollectとかStreamの使い方がよく分からない(´・ω・`)
コード読んで理解しろってことかな…

DDL

drop table if exists item;
create table if not exists item (
	id        bigint       not null auto_increment,
	name      varchar(255) not null,
	price     int          not null,
	create_at datetime(3)  not null,
	update_at datetime(3)  not null,
	primary key(id)
);

insert into item (name, price, create_at, update_at) values ('test1', 100, current_timestamp(3), current_timestamp(3));
insert into item (name, price, create_at, update_at) values ('test2', 200, current_timestamp(3), current_timestamp(3));
insert into item (name, price, create_at, update_at) values ('test3', 400, current_timestamp(3), current_timestamp(3));
insert into item (name, price, create_at, update_at) values ('test4', 1050, current_timestamp(3), current_timestamp(3));
insert into item (name, price, create_at, update_at) values ('test5', 150, current_timestamp(3), current_timestamp(3));
insert into item (name, price, create_at, update_at) values ('test6', 300, current_timestamp(3), current_timestamp(3));

件数を取得する方法

Daoメソッド定義
@Select
Long findByAllCount();
SQL
select
	count(*)
from
	item
使用例
Long count = dao.findByAllCount();

実行ログ

12 31, 2016 11:19:36 午後 com.example.dao.ItemDaoImpl findByAllCount
情報: [DOMA2220] ENTER  : クラス=[com.example.dao.ItemDaoImpl], メソッド=[findByAllCount]
12 31, 2016 11:19:36 午後 com.example.dao.ItemDaoImpl findByAllCount
情報: [DOMA2076] SQLログ : SQLファイル=[META-INF/com/example/dao/ItemDao/findByAllCount.sql],
select
	count(*)
from
	item
12 31, 2016 11:19:36 午後 com.example.dao.ItemDaoImpl findByAllCount
情報: [DOMA2221] EXIT   : クラス=[com.example.dao.ItemDaoImpl], メソッド=[findByAllCount]
6


件数を取得する系などは戻り値を数値型にしてSQLをcountを指定するだけで取れる感じです。

今回はここまで

MySQLのDATETIMEやTIMESTAMPでミリ秒などを設定したい

環境

MySQL5.7での確認

こんな感じの定義の場合

drop table if exists sample1;
create table if not exists sample1(
    id bigint       not null auto_increment,
    date1 datetime  not null,
    date2 timestame not null,
    primary key(id)
);

insert into sample1(date1, date2) values(current_timestamp, current_timestamp);

+----+---------------------+---------------------+
| id | date1               | date2               |
+----+---------------------+---------------------+
|  1 | 2016-12-30 11:04:16 | 2016-12-30 11:04:16 |
+----+---------------------+---------------------+

※秒までしか設定されていない感じ

内部的に値が設定されていたとしても取得した際の値が秒までの場合はミリ秒まで取得したくても対応できない

ミリ秒を設定したデータをinsertしてみる

insert into sample1(date1, date2) values('2016-12-30 11:04:16.123', '2016-12-30 11:04:16.123');

+----+---------------------+---------------------+
| id | date1               | date2               |
+----+---------------------+---------------------+
|  1 | 2016-12-30 11:04:16 | 2016-12-30 11:04:16 |
+----+---------------------+---------------------+

だめです(´・ω・`)

TIMESTAMPやDATETIMEに小数桁数を指定

drop table if exists sample1;
create table if not exists sample1(
    id bigint       not null auto_increment,
    date1 datetime(3)  not null,
    date2 timestamp(3) not null,
    primary key(id)
);

insert into sample1(date1, date2) values(current_timestamp, current_timestamp);

+----+-------------------------+-------------------------+
| id | date1                   | date2                   |
+----+-------------------------+-------------------------+
|  1 | 2016-12-30 11:14:03.000 | 2016-12-30 11:14:03.000 |
+----+-------------------------+-------------------------+

※小数桁を表現するようになった

小数桁のデータでinsert

insert into sample1(date1, date2) values('2016-12-30 11:04:16.123', '2016-12-30 11:04:16.123');

+----+-------------------------+-------------------------+
| id | date1                   | date2                   |
+----+-------------------------+-------------------------+
|  1 | 2016-12-30 11:04:16.123 | 2016-12-30 11:04:16.123 |
+----+-------------------------+-------------------------+

※設定できた(^^)

nowやcurrent_timestampでミリ秒を設定する

select now(3), current_timestamp(3), current_time(3);

+-------------------------+-------------------------+-----------------+
| now(3)                  | current_timestamp(3)    | current_time(3) |
+-------------------------+-------------------------+-----------------+
| 2016-12-30 11:18:43.408 | 2016-12-30 11:18:43.408 | 11:18:43.408    |
+-------------------------+-------------------------+-----------------+

※括弧内に桁数を指定すればミリ秒などを表示してくれる(^^)

わかったこと

  • DATETIMEやTIMESTAMPはミリ秒は定義時などで指定しないと値を設定しても正しく設定してくれない恐れがある
  • 最大6桁の小数桁を格納できる

期待

うーん、なんか設定ファイルでこの辺簡単に対応したいな〜
まあ使用する言語でどこまで保証するとかあるから難しいかも

Spring Bootで複数のフィルターを設定する

フィルタ内で全て1つでまとめるより

複数に分けたほうが管理し易いよね

やること

  1. Filterをimplementsしたクラスを作成
  2. @Componentsアノテーションは設定しない
  3. WebMvcConfigurerAdapterを継承したクラスで使用するフィルタを設定

フィルタ準備

Sample1Filter.java
package com.example.config.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

public class Sample1Filter implements Filter {
	
	private static final Logger logger = LoggerFactory.getLogger(Sample1Filter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 起動時に実行される
		logger.info("Sample1 Filter init");
	}
	 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// リクエスト発行時に実行される
		logger.info("Sample1 Filter doFilter start");
		chain.doFilter(request, response);
		logger.info("Sample1 Filter doFilter end");
	}

	@Override
	public void destroy() {
		// 終了時に実行される
		logger.info("Sample1 Filter destroy");
	}
	
}
Sample2Filter.java
package com.example.config.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

public class Sample2Filter implements Filter {
	
	private static final Logger logger = LoggerFactory.getLogger(Sample2Filter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 起動時に実行される
		logger.info("Sample2 Filter init");
	}
	 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// リクエスト発行時に実行される
		logger.info("Sample2 Filter doFilter start");
		chain.doFilter(request, response);
		logger.info("Sample2 Filter doFilter end");
	}

	@Override
	public void destroy() {
		// 終了時に実行される
		logger.info("Sample2 Filter destroy");
	}
	
}

フィルタ設定用クラス

WebConfig.java
package com.example.config;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.example.config.filter.Sample1Filter;
import com.example.config.filter.Sample2Filter;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
	
	@Bean
	public FilterRegistrationBean sampleFilter1() {		
		FilterRegistrationBean bean = new FilterRegistrationBean();
		bean.setFilter(new Sample1Filter());
		bean.setOrder(2);
		return bean;
	}
	
	@Bean
	public FilterRegistrationBean sampleFilter2() {		
		FilterRegistrationBean bean = new FilterRegistrationBean();
		bean.setFilter(new Sample2Filter());
		bean.setOrder(1);
		return bean;
	}
	
}

実行結果

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.3.RELEASE)

2016-12-30 17:23:45.163  INFO 10234 --- [           main] c.e.SpringSampleFilter01Application      : Starting SpringSampleFilter01Application on mshige1979MBA.local with PID 10234 (/Users/matsumotoshigeharu/Documents/workspace/spring_sample_filter01/target/classes started by matsumotoshigeharu in /Users/matsumotoshigeharu/Documents/workspace/spring_sample_filter01)
2016-12-30 17:23:45.167  INFO 10234 --- [           main] c.e.SpringSampleFilter01Application      : No active profile set, falling back to default profiles: default
2016-12-30 17:23:45.569  INFO 10234 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 17:23:45 JST 2016]; root of context hierarchy
2016-12-30 17:23:47.049  INFO 10234 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [class org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$9e478f9c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-12-30 17:23:47.130  INFO 10234 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
2016-12-30 17:23:47.672  INFO 10234 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-12-30 17:23:47.688  INFO 10234 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-12-30 17:23:47.689  INFO 10234 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-12-30 17:23:47.821  INFO 10234 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-12-30 17:23:47.822  INFO 10234 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2258 ms
2016-12-30 17:23:48.109  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-12-30 17:23:48.110  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-12-30 17:23:48.110  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-12-30 17:23:48.110  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-12-30 17:23:48.110  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'sample2Filter' to: [/*]
2016-12-30 17:23:48.110  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'sample1Filter' to: [/*]
2016-12-30 17:23:48.111  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-12-30 17:23:48.112  INFO 10234 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'messageDispatcherServlet' to [/services/*]
2016-12-30 17:23:48.145  INFO 10234 --- [ost-startStop-1] com.example.config.filter.Sample2Filter  : Sample2 Filter init
2016-12-30 17:23:48.146  INFO 10234 --- [ost-startStop-1] com.example.config.filter.Sample1Filter  : Sample1 Filter init
2016-12-30 17:23:48.481  INFO 10234 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 17:23:45 JST 2016]; root of context hierarchy
2016-12-30 17:23:48.567  INFO 10234 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/sample1/index],methods=[GET]}" onto public java.lang.String com.example.controller.Sample1Controller.index(org.springframework.ui.Model)
2016-12-30 17:23:48.571  INFO 10234 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-12-30 17:23:48.572  INFO 10234 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-12-30 17:23:48.634  INFO 10234 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 17:23:48.635  INFO 10234 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 17:23:48.701  INFO 10234 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 17:23:49.657  INFO 10234 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-12-30 17:23:49.792  INFO 10234 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-12-30 17:23:49.798  INFO 10234 --- [           main] c.e.SpringSampleFilter01Application      : Started SpringSampleFilter01Application in 5.262 seconds (JVM running for 5.969)
2016-12-30 17:23:58.031  INFO 10234 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-12-30 17:23:58.032  INFO 10234 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2016-12-30 17:23:58.072  INFO 10234 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 40 ms
2016-12-30 17:23:58.087  INFO 10234 --- [nio-8080-exec-1] com.example.config.filter.Sample2Filter  : Sample2 Filter doFilter start
2016-12-30 17:23:58.088  INFO 10234 --- [nio-8080-exec-1] com.example.config.filter.Sample1Filter  : Sample1 Filter doFilter start
2016-12-30 17:23:58.409  INFO 10234 --- [nio-8080-exec-1] com.example.config.filter.Sample1Filter  : Sample1 Filter doFilter end
2016-12-30 17:23:58.409  INFO 10234 --- [nio-8080-exec-1] com.example.config.filter.Sample2Filter  : Sample2 Filter doFilter end
2016-12-30 17:24:02.681  INFO 10234 --- [2)-192.168.10.3] inMXBeanRegistrar$SpringApplicationAdmin : Application shutdown requested.
2016-12-30 17:24:02.682  INFO 10234 --- [2)-192.168.10.3] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 17:23:45 JST 2016]; root of context hierarchy
2016-12-30 17:24:02.684  INFO 10234 --- [2)-192.168.10.3] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2016-12-30 17:24:03.757  INFO 10234 --- [ost-startStop-2] com.example.config.filter.Sample2Filter  : Sample2 Filter destroy
2016-12-30 17:24:03.757  INFO 10234 --- [ost-startStop-2] com.example.config.filter.Sample1Filter  : Sample1 Filter destroy

こんな感じですかね…

所感

なんとなくDIなどの動きはわかってきたけどBeanの仕組みがいまいちわかってない(´・ω・`)
データの流れを上手く把握しないと記載方法などに影響ができるの少しずつでも理解しておく必要がある。
日本語のマニュアルどっかにないかな〜

Spring Bootでフィルターを設定する

フィルタ

起動時、リクエスト、終了時などになんらかの処理を仕込みたい場合に設定する処理のこと
HTTPリクエスト時などで特定のヘッダが存在しない場合は処理を実施しないなどに使用する感じ?

設定方法

  1. Filterをimplemtsしたクラスを実装
  2. @Componentsアノテーションを付与

でイケる感じ

実装

SampleFilter.java
package com.example.config.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SampleFilter implements Filter {
	
	private static final Logger logger = LoggerFactory.getLogger(SampleFilter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 起動時に実行される
		logger.info("Sample Filter init");
	}
	 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// リクエスト発行時に実行される
		logger.info("Sample Filter doFilter start");
		chain.doFilter(request, response);
		logger.info("Sample Filter doFilter end");
	}

	@Override
	public void destroy() {
		// 終了時に実行される
		logger.info("Sample Filter destroy");
	}
	
}

※これだけでアプリにフィルタが実装される感じらしい

実行ログ

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.3.RELEASE)

2016-12-30 16:44:59.624  INFO 10081 --- [           main] c.e.SpringSampleFilter01Application      : Starting SpringSampleFilter01Application on mshige1979MBA.local with PID 10081 (/Users/matsumotoshigeharu/Documents/workspace/spring_sample_filter01/target/classes started by matsumotoshigeharu in /Users/matsumotoshigeharu/Documents/workspace/spring_sample_filter01)
2016-12-30 16:44:59.626  INFO 10081 --- [           main] c.e.SpringSampleFilter01Application      : No active profile set, falling back to default profiles: default
2016-12-30 16:45:00.109  INFO 10081 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 16:45:00 JST 2016]; root of context hierarchy
2016-12-30 16:45:01.110  INFO 10081 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [class org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$311b2b8c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-12-30 16:45:01.172  INFO 10081 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
2016-12-30 16:45:01.634  INFO 10081 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-12-30 16:45:01.651  INFO 10081 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-12-30 16:45:01.653  INFO 10081 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-12-30 16:45:01.805  INFO 10081 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-12-30 16:45:01.805  INFO 10081 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1700 ms
2016-12-30 16:45:02.008  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-12-30 16:45:02.010  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'messageDispatcherServlet' to [/services/*]
2016-12-30 16:45:02.013  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-12-30 16:45:02.014  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-12-30 16:45:02.014  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-12-30 16:45:02.014  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-12-30 16:45:02.014  INFO 10081 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'sampleFilter' to: [/*]
2016-12-30 16:45:02.036  INFO 10081 --- [ost-startStop-1] com.example.config.filter.SampleFilter   : Sample Filter init
2016-12-30 16:45:02.341  INFO 10081 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 16:45:00 JST 2016]; root of context hierarchy
2016-12-30 16:45:02.421  INFO 10081 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/sample1/index],methods=[GET]}" onto public java.lang.String com.example.controller.Sample1Controller.index(org.springframework.ui.Model)
2016-12-30 16:45:02.426  INFO 10081 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-12-30 16:45:02.426  INFO 10081 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-12-30 16:45:02.470  INFO 10081 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 16:45:02.471  INFO 10081 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 16:45:02.514  INFO 10081 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-30 16:45:03.050  INFO 10081 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-12-30 16:45:03.122  INFO 10081 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-12-30 16:45:03.127  INFO 10081 --- [           main] c.e.SpringSampleFilter01Application      : Started SpringSampleFilter01Application in 4.188 seconds (JVM running for 5.127)
2016-12-30 16:45:13.216  INFO 10081 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-12-30 16:45:13.216  INFO 10081 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2016-12-30 16:45:13.233  INFO 10081 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms
2016-12-30 16:45:13.249  INFO 10081 --- [nio-8080-exec-1] com.example.config.filter.SampleFilter   : Sample Filter doFilter start
2016-12-30 16:45:13.461  INFO 10081 --- [nio-8080-exec-1] com.example.config.filter.SampleFilter   : Sample Filter doFilter end
2016-12-30 16:45:18.987  INFO 10081 --- [nio-8080-exec-2] com.example.config.filter.SampleFilter   : Sample Filter doFilter start
2016-12-30 16:45:18.992  INFO 10081 --- [nio-8080-exec-2] com.example.config.filter.SampleFilter   : Sample Filter doFilter end
2016-12-30 16:45:23.424  INFO 10081 --- [2)-192.168.10.3] inMXBeanRegistrar$SpringApplicationAdmin : Application shutdown requested.
2016-12-30 16:45:23.424  INFO 10081 --- [2)-192.168.10.3] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3a93b025: startup date [Fri Dec 30 16:45:00 JST 2016]; root of context hierarchy
2016-12-30 16:45:23.427  INFO 10081 --- [2)-192.168.10.3] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2016-12-30 16:45:24.489  INFO 10081 --- [ost-startStop-2] com.example.config.filter.SampleFilter   : Sample Filter destroy

動きました
作成するだけで起動するのはちょっと不安な感じもするけど楽といえば楽ですね(^^)

所感

どんな処理を設定するかは今後考えるとしてリクエストの前後などに処理を簡単に設定できるのは結構便利な気がします。
RestAPIなどのトークン制御などに使えるのかも…