一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加した初日です。クリックしてイベントの詳細をご覧ください。
1. HandlerMethodArgumentResolverの役割とそのメソッドの説明:
HandlerMethodArgumentResolverは、次の2つのメソッドを持つインターフェイスです。
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
复制代码
メソッド名を見れば、おそらく推測できます。
supportsParameterメソッドの戻り値はブール値です。その機能は、Controller層のパラメーターが条件を満たしているかどうかを判断することです。条件が満たされている場合は、resolveArgumentメソッドが実行されます。満たされていない場合は、スキップしてください。
resolveArgumentメソッド。supportsParameterメソッドがtrueを返した場合にのみ呼び出されます。これは、一部のビジネスを処理し、コントローラー層でこのパラメーターに戻り値を割り当てるために使用されます。
HandlerMethodArgumentResolverはパラメーターリゾルバーとして理解できます。HandlerMethodArgumentResolverインターフェイスを実装するクラスを作成することで、コントローラーレイヤーのメソッドパラメーターを変更できます。
2.プロジェクトの実現
1.たとえば、JWTでログインした後、次のインターフェースを介して、現在のログイン者の情報や許可メニューなどの詳細情報を取得する必要があります。
@GetMapping("/routes")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
public R<List<MenuVO>> routes(HttpServletRequest request) {
Claims claims = getClaims(request);
if (claims == null) {
return null;
} else {
Long userId = claims.get("user_id");
String roleId = claims.get("role_id");
String deptId = claims.get("dept_id");
String account = claims.get("account");
String roleName = claims.get("role_name");
String userName = claims.get("user_name");
User user = new User();
user.setUserId(userId);
user.setTenantId(tenantId);
user.setAccount(account);
user.setRoleId(roleId);
user.setDeptId(deptId);
user.setRoleName(roleName);
user.setUserName(userName);
}
List<MenuVO> list = menuService.routes((user == null || user.getUserId() == 0L) ? null : user.getRoleId());
return R.data(list);
}
复制代码
ただし、プロジェクトでは、各インターフェイスがこの方法でパラメーターを取得する必要があるため、コードが肥大化しすぎています。これを少し変更して、HandlerMethodArgumentResolverインターフェイスを使用できます。
2.最初に、このインターフェイスのメソッドを実装するための実装クラスを記述します。
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
private static final Logger log = LoggerFactory.getLogger(TokenArgumentResolver.class);
public TokenArgumentResolver() {
}
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(User.class);
}
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
return SecureUtil.getUser();
}
}
复制代码
次に、この実装クラスをプロジェクトのインターセプトに追加します。
@Configuration(
proxyBeanMethods = false
)
@EnableCaching
@Order(-2147483648)
public class MyWebMvcConfiguration implements WebMvcConfigurer {
private static final Logger log = LoggerFactory.getLogger(BladeWebMvcConfiguration.class);
public MyWebMvcConfiguration() {
}
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new TokenArgumentResolver());
}
}
复制代码
このように、プロジェクトインターフェイスが要求されると、カスタムTokenArgumentResolverクラスに入り、インターフェイスクラスとパラメーター情報を解決します。
次に、インターフェイスは次のように記述できます。
@GetMapping("/routes")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
public R<List<MenuVO>> routes(User user) {
List<MenuVO> list = menuService.routes((user == null || user.getUserId() == 0L) ? null : user.getRoleId());
return R.data(list);
}
复制代码
このように、各インターフェースは要求ヘッダー内のトークンを解析する必要がなく、トークンに対応するユーザー情報を取得できます。