【Spring Boot】カスタムデータバインド
SpringBoot
2021/09/19
はじめに
例えば認証トークンなど、Controller 以下でリクエストヘッダーの情報を取得したい場合、以下のようにHttpServletRequest
を使用します。
@GetMapping
public String getToken(HttpServletRequest request) {
return getToken.orElse("");
}
private Optional<String> getToken(HttpServletRequest request) {
String authorization = request.getHeader("Authorization");
if (authorization == null || authorization.isEmty()) {
return Optional.empty();
}
try {
String identifier = authorization.substring(0, 6);
if (!"Bearer".equals(identifier)) {
return Optional.empty();
}
String token = authorization.substring(7);
return Optional.of(token);
} catch (StringIndexOutofBoundsException e) {
return Optional.empty();
}
}
正直、上記のgetToken
のようにメソッドを用意してもよいのですが、以下のようにアノテーションを利用し、Controller のパラメーターとして取得することを考えていきます。
@GetMapping
public String getToken(@AuthToken String token) {
return token;
}
アノテーションの作成
以下のようにアノテーションを作成します。
今回はパラメーター用にしたいため、@Target
にはElementType.PARAMETER
を指定します。
AuthToken.java
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthToken {
}
パラメーターの設定処理
@AuthToken
の指定があるパラメーターに対し、リクエストヘッダーのAuthorization
の内容を設定する処理を実装していきます。
これを実現するためには、HandlerMethodArgumentResolver
を implements したクラスを作成します。
AuthTokenResolver.java
public class AuthTokenResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameter(AuthToken.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
//トークンの取得処理(省略...)
String token = getToken(request).orElse(null);
return token;
}
}
HandlerMethodArgumentResolver
では、supportsParameter()
とresolveArgument()
の 2 つのメソッドを実装します。
supportsParameter()
で作成したアノテーションの紐付けを行い、resolveArgument()
で具体的なパラメーターの設定処理を定義します。
あとはこの処理が実行されるように、WebMvcConfigure
で登録をします。
WebMvcConfig.java
@Configuration
public class WebMvcConfig implements WebMvcConfigure {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new AuthTokenResolver());
}
}
おわりに
上記では説明していませんが、リクエストヘッダーを取得する場合は@RequestHeader
を使用します。
@GetMapping
public String getToken(@RequestHeader("Authorization") String authorization) {
//...
}
なのでただ単にリクエストヘッダーの情報を読み込む場合は必要ありません。 今回のようにリクエストヘッダーの内容を分解して…、みたいなことを行う場合は有効かもしれませんので是非ご参考までに。