1. Introduction
In Java development, most interfaces need user login to execute business logic, so there will be a lot of repeated code for verifying user login and obtaining user information, which is not easy to be complicated, but also easy to miss.
2. How does Spring implement request parameter injection
public class User {
private Long id;
private String name;
}
@GetMapping("param")
public String param(User user) {
System.out.println(user);
return "param";
}
Copy the code
In Spring, to retrieve queryString parameters, simply add an argument of the same name to the Controller method or an object with the same name as a field. This approach is elegant and isolates HttpRequest’s API, which is a nice touch. Spring to realize this kind of elegant way of injection, it depends on the extended interface HandlerMethodArgumentResolver
3. The extension HandlerMethodArgumentResolver
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
Copy the code
SupportsParameter HandlerMethodArgumentResolver defines two methods, to determine whether or not to perform injection parameters, resolveArgument execution parameter parsed and into the Controller method.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface UserInfo {
boolean required(a) default true;
}
Copy the code
First we need to define an annotation @userInfo to mark the object we want to inject. The annotation needs to be implemented at run time. @userInfo has a Reqiured property that marks whether the interface must be logged in to be accessible, for some interfaces that display different data depending on whether the user is logged in or not.
@GetMapping("/required")
public String required(@UserInfo User user) {
System.out.println(user);
return "required";
}
@GetMapping("notRequired")
public String notRequired(@UserInfo(required = false) User user) {
System.out.println(user);
return "not required";
}
Copy the code
Add the User parameter to Controller with the @userinfo tag
public class Token2UserResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// The method argument has the @userinfo flag
return parameter.hasParameterAnnotation(UserInfo.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
/ / get the @ the UserInfo
UserInfo userInfo = parameter.getParameterAnnotation(UserInfo.class);
// Get access-token from header
String token = webRequest.getHeader("access-token");
if ((token == null || token.isEmpty())) {
if (userInfo.required()) {
// If the token does not exist and you must log in to the interface, throw an exception and return the corresponding status code to the preceding segment together with unified exception processing
throw new RuntimeException("401");
} else {
// If you do not have to log in, do not process it
return null; }}// Parse the token into a User object
User user = null;
if (token.equals("token-a")) {
user = new User(1L."user-A");
} else if (token.equals("token-b")) {
user = new User(2L."user-B");
}
returnuser; }}Copy the code
Implement HandlerMethodArgumentResolver, this simple analytical process, simulates a token can be used in practical development redis or JWT scheme implementation. It is important to note that this is not just about injecting user information, but also about enforcing interface logins. When the @userInfo attribute is true, an exception will be thrown if there is no login, and unified exception handling allows for access control and elegant responses.
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(newToken2UserResolver()); }}Copy the code
Finally, add Token2UserResolver to the parser chain via WebMvcConfigurer provided by Spring. The result is an elegant user information parsing tool. The business developer can focus on the implementation of the business without worrying about obtaining and verifying user information.