当前位置:首页
> .html
导读:1. 定义 User 类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
...
1. 定义 User 类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
private Long id;
private String name;
}
2. 定义 CurrentUser 注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义 当前用户 注解
* 注解 参数
* 此注解在验证token通过后,获取当前token包含用户
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
3. 实现 HandlerMethodArgumentResolver
import lombok.extern.slf4j.Slf4j;
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;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Optional;
/**
* @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;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
Optional<String> id = getValue(request, "id");
Optional<String> name = getValue(request, "name");
return User.builder()
.id(id.map(Long::parseLong).orElse(null))
.name(name.orElse(null))
.build();
}
private Optional<String> getValue(HttpServletRequest request, String name) {
return Arrays.stream(request.getCookies())
.filter(c -> c.getName().equals(name))
.findFirst()
.map(Cookie::getValue);
}
}
4. 配置 WebMvcConfig
把 CurrentUserMethodArgumentResolver
添加到 SpringMVC 中。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new CurrentUserMethodArgumentResolver());
}
}
5. 通过 Controller 进行测试
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class DemoController {
@GetMapping("/test")
public User test(@CurrentUser User user) {
log.info("user: {}", user);
return user;
}
}
启动服务,通过 postman 调用 /test
接口进行测试。
5.1 cookie 为空

cookie 为空
5.2 cookie 只包含 id
id=1

cookie 只包含id
5.3 cookie 包含id和 name
id=1;name=joy

cookie 包含id和 name
总结
- 1)定义你想要获取的 Context 数据对象
- 2)定义一个你想要在 Controller 方法中识别参数的注解
- 3)实现
HandlerMethodArgumentResolver
,并在其使用第( 1)和第( 2)步骤定义的数据对象和注解。 - 4)通过
WebMvcConfigurationSupport
将第 (3)步实现的HandlerMethodArgumentResolver
添加到 SpringMVC 中。 - 5)此后就可以在 Controller 中实现第( 1)和第( 2)步骤定义的数据对象和注解。
发表评论: