SpringBoot implements login user acquisition using custom annotations.
Introduction to the
Annotations are a type of metadata that can be added to Java code. Classes, methods, variables, parameters, and packages can all be decorated with annotations. Annotations have no direct effect on the code they modify.
So what can it be used for? Do logging, achieve login user acquisition and so on…
This article will show you how to use custom annotations for login user retrieval in a few simple steps, without further ado.
- Start by defining an annotation class that can be used to get the user ID after the user logs in successfully.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/ * * *@author ChenTaWen
* @version1.0 * /
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AuthUserId {
}
Copy the code
Notes:
@TargeWhat type of annotation does the specification indicate/** class, interface (including annotation type) or enumeration declaration */
TYPE,
/** Attribute declaration */
FIELD,
/** method declaration */
METHOD,
/** Method formal parameter declaration */
PARAMETER,
/** constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** package declaration */
PACKAGE
-------------------------------------------------------------------------------
@RetentionThe annotation life cycle has three phases:1Java source file stage;2, compile theclassFile stage; 3. Operation stage. Also usedRetentionPolicyAn enumeration type defines three phases:SOURCE.CLASS.RUNTIME-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 1, if an annotation is defined asRetentionPolicy.SOURCE, then it will be limited toJavaIn the source file, the annotation neither participates in compilation nor has any effect at runtime. The annotation has the same effect as a comment and can only be readJavaFile people see; 2. If an annotation is defined asRetentionPolicy.CLASS, it will compile toClassFile, then the compiler can do some processing on annotations at compile time, but at run timeJVM(JavaThe virtual machine will ignore it and we cannot read it at runtime; 3. If an annotation is defined asRetentionPolicy.RUNTIMEThen the annotation can be loaded during the runtime load phaseClassIn the object. So at runtime, we can get this annotation through reflection and execute different program code segments by determining whether there is this annotation or the value of the attribute in this annotation. Custom annotations are almost always used in our actual developmentRetentionPolicy.RUNTIME; By default, custom annotations are usedRetentionPolicy.CLASS. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - the @DocumentedAnnotations are used to specify whether custom annotations can be defined along with themjavaFile generation toJavaDocIn the documentation. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - the @InheritedAnnotation specifies that if a custom annotation is written in the declaration part of the parent class, the declaration part of the child class automatically owns the annotation. Note: [@InheritedAnnotations are only for those at signsTargetIs defined asElementType.TYPECustom annotations are in effect]Copy the code
- Define a class to implement HandlerMethodArgumentResolver rewrite its method (processing method for parameters of the parser)
import com.auth0.jwt.interfaces.DecodedJWT;
import com.chentawen.springbootall.config.exception.MyException;
import com.chentawen.springbootall.util.JWTUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/ * * *@author ChenTaWen
* @version1.0 * /
public class UserIdResolver implements HandlerMethodArgumentResolver {
/** * Call resolveArgument */ if true is returned
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(AuthUserId.class);
}
/ * * *@AuthUserIdPerform business processing */
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
// Get the token from the request header
String authorization = nativeWebRequest.getHeader("token");
if ("".equals(authorization)) {
throw new MyException("Token cannot be empty");
}
// Get userId from token
DecodedJWT verify = JWTUtils.verify(authorization);
return verify.getClaim("userId").asInt(); }}Copy the code
- Inject the parser into SpirngMVC
import com.chentawen.springbootall.config.annotation.UserIdResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/ * * *@author admin
*/
@Configuration
public class IntercaptorConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(newUserIdResolver()); }}Copy the code
- Write Controller to test
import com.baomidou.mybatisplus.extension.api.R;
import com.chentawen.springbootall.config.annotation.AuthUserId;
import com.chentawen.springbootall.config.exception.MyException;
import com.chentawen.springbootall.model.User;
import com.chentawen.springbootall.util.JWTUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/ * * *@author admin
*/
@RestController
@RequestMapping("user")
public class UserLoginController {
@Value("${Login.username}")
private String realUsername;
@Value("${Login.password}")
private String realPassword;
@GetMapping("login")
public String login(String username, String password) {
if (username.equals(realUsername) && password.equals(realPassword)) {
User u = new User();
u.setId(99);
u.setPassword(password);
u.setUsername(username);
return JWTUtils.getToken(u);
}
return "Login failed! Wrong account or password!";
}
@GetMapping("getUserId")
public R<Integer> getUserId(@AuthUserId Integer userId) {
returnR.ok(userId); }}Copy the code
- Use Postman for testing
Login interface – Returns Jwt
Test custom annotation @authUserId – request header token, access getUserId method
Note: For more practical project development, this article integrates MyBatis-Plus, Jwt, relevant source code and dependencies please see:
SpringBoot integrates MyBatis-Plus and MyBatis-Plus code generation tools
SpringBoot integration with Jwt
Need source can drop! What doubt can comment area to ask!