1. 定义 User 类
代码语言:txt复制import lombok.AllArgsConstructor;代码语言:txt复制import lombok.Builder;代码语言:txt复制import lombok.Data;代码语言:txt复制import lombok.NoArgsConstructor;代码语言:txt复制@Data代码语言:txt复制@NoArgsConstructor代码语言:txt复制@AllArgsConstructor代码语言:txt复制@Builder代码语言:txt复制public class User {代码语言:txt复制 private Long id;代码语言:txt复制 private String name;代码语言:txt复制}2. 定义 CurrentUser 注解
代码语言:txt复制import java.lang.annotation.ElementType;代码语言:txt复制import java.lang.annotation.Retention;代码语言:txt复制import java.lang.annotation.RetentionPolicy;代码语言:txt复制import java.lang.annotation.Target;代码语言:txt复制/**代码语言:txt复制 * 自定义 当前用户 注解
* 注解 参数
* 此注解在验证token通过后,获取当前token包含用户
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}3. 实现 HandlerMethodArgumentResolver
代码语言:txt复制import lombok.extern.slf4j.Slf4j;代码语言:txt复制import org.springframework.core.MethodParameter;代码语言:txt复制import org.springframework.web.bind.support.WebDataBinderFactory;代码语言:txt复制import org.springframework.web.context.request.NativeWebRequest;代码语言:txt复制import org.springframework.web.method.support.HandlerMethodArgumentResolver;代码语言:txt复制import org.springframework.web.method.support.ModelAndViewContainer;代码语言:txt复制import javax.servlet.http.Cookie;代码语言:txt复制import javax.servlet.http.HttpServletRequest;代码语言:txt复制import java.util.Arrays;代码语言:txt复制import java.util.Optional;代码语言:txt复制/**代码语言:txt复制 * @CurrentUser 注解 解析器
*/
@Slf4j
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 1. User 类的对象是否可以分配给当前的方法参数
boolean assignable = parameter.getParameterType().isAssignableFrom(User.class);
// 2. 当前方法参数上是否有 CurrentUser 的注解
boolean hasAnnotation = parameter.hasParameterAnnotation(CurrentUser.class);
return assignable && hasAnnotation;
}代码语言:txt复制 @Override代码语言:txt复制 public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {代码语言:txt复制 HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);代码语言:txt复制 Optional<String> id = getValue(request, "id");代码语言:txt复制 Optional<String> name = getValue(request, "name");代码语言:txt复制 return User.builder()代码语言:txt复制 .id(id.map(Long::parseLong).orElse(null))代码语言:txt复制 .name(name.orElse(null))代码语言:txt复制 .build();代码语言:txt复制 }代码语言:txt复制 private Optional<String> getValue(HttpServletRequest request, String name) {代码语言:txt复制 return Arrays.stream(request.getCookies())代码语言:txt复制 .filter(c -> c.getName().equals(name))代码语言:txt复制 .findFirst()代码语言:txt复制 .map(Cookie::getValue);代码语言:txt复制 }代码语言:txt复制}4. 配置 WebMvcConfig
把 CurrentUserMethodArgumentResolver 添加到 SpringMVC 中。
import org.springframework.context.annotation.Configuration;代码语言:txt复制import org.springframework.web.method.support.HandlerMethodArgumentResolver;代码语言:txt复制import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;代码语言:txt复制import java.util.List;代码语言:txt复制@Configuration代码语言:txt复制public class WebMvcConfig extends WebMvcConfigurationSupport {代码语言:txt复制 @Override代码语言:txt复制 protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {代码语言:txt复制 argumentResolvers.add(new CurrentUserMethodArgumentResolver());代码语言:txt复制 }代码语言:txt复制}5. 通过 Controller 进行测试
代码语言:txt复制import lombok.extern.slf4j.Slf4j;代码语言:txt复制import org.springframework.web.bind.annotation.GetMapping;代码语言:txt复制import org.springframework.web.bind.annotation.RestController;代码语言:txt复制@RestController代码语言:txt复制@Slf4j代码语言:txt复制public class DemoController {代码语言:txt复制 @GetMapping("/test")代码语言:txt复制 public User test(@CurrentUser User user) {代码语言:txt复制 log.info("user: {}", user);代码语言:txt复制 return user;代码语言:txt复制 }代码语言:txt复制}启动服务,通过 postman 调用 /test 接口进行测试。
5.1 cookie 为空
cookie 为空
5.2 cookie 只包含 id
代码语言:txt复制id=1cookie 只包含id
5.3 cookie 包含id和 name
代码语言:txt复制id=1;name=joycookie 包含id和 name


