web應用中常會用到用戶信息,通常都是從會話中獲取,不過這樣不優雅,類似的代碼處處都是,但願能夠經過spring的特性,在我須要的時候能夠自動裝配。web
1.登陸時產生token,同時把token與反序列化的用戶信息放入redis中;
2.訪問時攜帶token,網關層進行攔截,同時從redis經過token將用戶信息放入header中;
3.業務層,經過攔截器攔截請求,從header中獲取反序列化的用戶信息,放入Request中;
4.經過參數分解器,從Request中獲取參數注入redis
HandlerMethodArgumentResolver:https://www.jianshu.com/p/ac9...spring
BeanPostProcessor:https://blog.csdn.net/zhyh198...json
BeanPostProcessor和BeanFactoryProcessor淺析:https://www.jianshu.com/p/fb3...app
public class UserResolveFilter extends ZuulFilter { /** * 請求攔截類型 * * @return */ @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 20; } /** * 哪些請求要被攔截 * * @return */ @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); // 端口號以後的請求地址 return request.getRequestURI().startsWith("/core-server"); } @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); ctx.getZuulRequestHeaders().remove("user"); HttpServletRequest request = ctx.getRequest(); String token = request.getHeader("token"); if (!StringUtils.isBlank(token)) { // 這裏獲取token後,能夠完成本身的映射操做 ctx.addZuulRequestHeader("user", "{\"id\":1,\"name\":\"jiaotd\",\"age\":18}"); } return null; } }
@Configuration @Slf4j public class Config { @Bean public UserResolveFilter userCenterResolveUserFilter() { log.info("init UserResolveFilter"); return new UserResolveFilter(); } }
@Configuration @WebFilter(filterName = "userInfoResolverFilter", urlPatterns = "/*") public class UserInfoResolverFilter implements Filter { //@WebFilter 用於將一個類聲明爲過濾器,該註解將會在部署時被容器處理,容器將根據具體的屬性配置將相應的類部署爲過濾器 @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("UserInfoResolverFilter init()....."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String json = ((HttpServletRequest) servletRequest).getHeader("user"); log.info("請求頭中的User爲:{}", json); User user = JSON.parseObject(URLDecoder.decode(json, "utf-8"), User.class); servletRequest.setAttribute("user", user); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { log.info("UserInfoResolverFilter destroy()....."); } }
public class UserArgumentResolver implements HandlerMethodArgumentResolver { /** * 參數類型是User的執行 #resolveArgument 方法 * * @param methodParameter * @return */ @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.getParameterType() == User.class; } /** * 賦值 * * @param methodParameter * @param modelAndViewContainer * @param nativeWebRequest * @param webDataBinderFactory * @return * @throws Exception */ @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { User user = (User) nativeWebRequest.getAttribute("user", RequestAttributes.SCOPE_REQUEST); return user; } }
@Component public class ArgumentResolverPostProcessor implements BeanPostProcessor { /** * spring 初始化 Bean 操做 * * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof RequestMappingHandlerAdapter) { //requestMappingHandlerAdapter進行修改 RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean; List<HandlerMethodArgumentResolver> argumentResolvers = adapter.getArgumentResolvers(); //添加自定義參數處理器 argumentResolvers = addArgumentResolvers(argumentResolvers); adapter.setArgumentResolvers(argumentResolvers); } return null; } private List<HandlerMethodArgumentResolver> addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); //將自定的添加到最前面 resolvers.add(new UserArgumentResolver()); //將本來的添加後面 resolvers.addAll(argumentResolvers); return resolvers; }
@RestController @RequestMapping("/core") public class CoreController { @GetMapping("/user") public User getUser(User user) { return user; } }