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で複数のテーブルを結合した結果を取得する
複数のテーブルを連結したい
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 | +-------------------------+-------------------------+-----------------+
※括弧内に桁数を指定すればミリ秒などを表示してくれる(^^)
参考
MySQL :: MySQL 5.6 リファレンスマニュアル :: 11.3.5 TIMESTAMP および DATETIME の自動初期化および更新機能
MySQL 5.6.4でマイクロ秒までサポート(TIME, DATETIME, TIMESTAMP) | キムラデービーブログ
わかったこと
- DATETIMEやTIMESTAMPはミリ秒は定義時などで指定しないと値を設定しても正しく設定してくれない恐れがある
- 最大6桁の小数桁を格納できる
期待
うーん、なんか設定ファイルでこの辺簡単に対応したいな〜
まあ使用する言語でどこまで保証するとかあるから難しいかも
Spring Bootで複数のフィルターを設定する
フィルタ内で全て1つでまとめるより
複数に分けたほうが管理し易いよね
やること
- Filterをimplementsしたクラスを作成
- @Componentsアノテーションは設定しない
- 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リクエスト時などで特定のヘッダが存在しない場合は処理を実施しないなどに使用する感じ?
実装
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などのトークン制御などに使えるのかも…