spring-boot-starter-security を入れたら認証画面が!
WebSecurityConfigurerAdapter#configure(HttpSecurity) で form 認証を有効化しているのでこれをディスる。
WebSecurityConfigurerAdapterを継承した Spring コンポーネントをスキャン対象に含めれば良い。
ちょっと待って!そのUserDetails、本当に必要ですか?
概要
Spring Boot の認証を実装してみた系のサンプルでよく UserDetails や UserDetailsService が用いられているが、必然性が不明なものがほとんどである。
(おそらく当の実装者も理解していない1。)
ファイル出力先にServletContext#getRealPathを使うな
タイトルに書いたような、ファイル出力先として ServletContext#getRealPath を利用しているサンプルコードが見つかる、と聞いて検索してみたところ、日本語、非日本語にかかわらず確かにそのようなサンプルコードは散見されました。
例えば Qiita では(順不同):
元号が令和に変わったことを知らない人のための日付処理方法
問題
JapaneseDate.of(や LocalDate.of)を使うと厳密(strict)に検証されてしまう。
結果、例外が出る。
// 平成31年6月12日
final JapaneseDate today = JapaneseDate.of(JapaneseEra.HEISEI, 31, 6, 12);
System.out.println(today);
Exception in thread "main" java.time.DateTimeException: year, month, and day not valid for Era
at java.base/java.time.chrono.JapaneseDate.of(JapaneseDate.java:231)
at com.github.yukihane.datetime.App.main(App.java:21)
解決策
JapaneseChronology#resolveDate(や IsoChronology#resolveDate)を使えばゆるふわ(lenient)な検証でゆるしてくれたりも。
SimpleDateFormat もこれもうわかんねぇな
結果
1.8
H
11
平成
環境
1.8
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
11
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
コード
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(final String[] args) {
final Date date = date(2010, 3, 4);
final SimpleDateFormat format = new SimpleDateFormat("G", new Locale("ja", "JP", "JP"));
System.out.println(format.format(date));
}
private static Date date(final int year, final int month, final int dayOfMonth) {
final long time = LocalDate.of(year, month, dayOfMonth)
.atStartOfDay(ZoneOffset.ofHours(9)).toEpochSecond() * 1000;
return new Date(time);
}
}
関連(しない)
関連(する)
From JDK 9 onwards, the default locale data is the data derived from the Unicode Consortium’s Common Locale Data Repository (CLDR). Please refer https://www.unicode.org/cldr/charts/33/by_type/date_&_time.japanese.html
…
The short display format for Heisei is 平成 in the ja locale in CLDR data. Hence the difference in the result.
%s に null を渡したらどうなるんだっけ
こたえ
文字列 null が出力される。
コード
final String text = null;
System.out.printf("%s", text);
参考
For category General, Character, Numberic, Integral and Date/Time conversion, unless otherwise specified, if the argument arg is null, then the result is “null”.
リンク先の表にある通り、 s はカテゴリ"general"に属す。ちなみに日本語ではこうなっている(わかりにくい):
DateTimeFormatter とかこれもうわかんねぇな
コード
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class App {
private static String format(final LocalDate date, final String pattern) {
return date.format(DateTimeFormatter.ofPattern(pattern, Locale.JAPAN));
}
public static void main(final String[] args) {
final LocalDate today = LocalDate.of(2019, 6, 4);
System.out.println(format(today, "M"));
System.out.println(format(today, "MM"));
System.out.println(format(today, "MMM"));
System.out.println(format(today, "MMMM"));
System.out.println(format(today, "MMMMM"));
System.out.println(format(today, "MMMMMM"));
}
}
結果
| パターン | 結果 |
|---|---|
| M | 6 |
| MM | 06 |
| MMM | 6 月 |
| MMMM | 6 月 |
| MMMMM | 6 |
| MMMMMM | IllegalArgumentException: Too many pattern letters: M |
$ java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
参考(にならなかった)リンク
参考(にややなった)リンク
関連(しない)
…Spring Bootで コンポーネント外からコンポーネントを取得したかった
動機
CDI で言うところの CDI.current().getBeans(...) とか CDI.current().select(...)とかそんな感じのことをやりたかった。
参考リファレンス
ドキュメントでは、やりたいことが書いてあるように見えたのはこのセクション
…Spring Boot 2.1 でテスト時 @Bean を挿げ替えたかった
動機
ユニットテスト実行時に java.time.Clock を特定の時間に固定して再現性のあるテスト(現在の時刻に依存しないテスト)を作成したかった。
考え方/方針
@Configuration で @Bean を定義して Clock をインジェクションできるようにし、実装ではそれを用いる。
text/plain で JSON を投げつけてくるヤツに対処する
の別解。
@Autowired
private RestTemplateBuilder builder;
...
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN));
final RestTemplate restTemplate = builder.additionalMessageConverters(converter).build();
ちなみに上記のようにコンバータを明示的に設定しない場合だと次のような例外になる :
…Java9以降.propertiesファイルをUTF-8で書けるようになった、は正しい?
解答
正しくない。
- Java9(JEP226)で変わったのはリソースバンドルの取り扱い(PropertyResourceBundle) であって プロパティファイル
.properties全般の話ではない。 - プロパティファイル
.propertiesの文字エンコーディングについての取り決めはない。それを取り扱うプログラム次第でありUTF-8を正しく認識してくれるとは限らない。- 標準 API で
UTF-8として(読もうと思えば)読めるようになったのは 1.6 からであって 9 からではない。ちなみに 1.5 以前はISO 8859-1前提。
- 標準 API で
背景
私はうろ覚えで何となく、現在の Java では .properties ファイルを UTF-8 で書ける、ascii2nativeは過去の遺物になった、のだと思いこんでいました。
ところが Spring Boot の application.properties に UTF-8 で日本語を書いたところ文字化けしてしまい、あれ、もしかして自分の理解が間違っているのかと思い調べ直したのがこの記事です。
Testing the Web Layer のコードを JUnit Jupiter にマイグレーションしてみる
概要
(追記: ここで試したのは2.1.4.RELEASE時点のもの。2.2.0.M3以降では #14736の通り JUnit5 がデフォルトになっている模様。)
spring-boot-starter-test の JUnit5 対応はこちらの issue:
…Spring Validator(でラップされたBean Validation)のメッセージをi18nしたときの覚え書き
やりたかったこと
- BeanValidation のプロパティファイル
ValidationMessages.propertiesでなく、 Spring のメッセージプロパティに統合したい。- Spring のメッセージプロパティとは?
Accept-Languageベースでメッセージを国際化したい。
調べた
Spring のメッセージプロパティファイルはどこ?
これはキーワード “site:spring.io i18n message” でググるとすぐ見つかった。
…