自定义注解的使用(将request参数中的数据解释成对象)

本文介绍如何在项目中利用自定义注解处理controller方法中的请求参数,通过注解将cookie中的用户信息解析并转换为对象,简化用户登录验证过程。通过创建注解类、实现注解处理方法并将处理类加入WebMvcConfigurerAdapter,实现用户信息的自动获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中,每个controller方法都需要验证用户登录,这里工程写了一个简单的注解,来将cookie中的用户信息还原成对象

注解类

package com.cheshangma.operation.wx.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;



@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
//@Retention(RetentionPolicy.SOURCE)    //注解仅存在于源码中,在class字节码文件中不包含
//@Retention(RetentionPolicy.CLASS)       // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
//@Retention(RetentionPolicy.RUNTIME)   // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented
public @interface ObjectConvertAnno {

  /**
   * 指定该参数的值是否允许为 null 默认是不允许 Whether the parameter is required.
   * <p>
   * Default is <code>true</code>, leading to an exception thrown in case of the parameter missing
   * in the request. Switch this to <code>false</code> if you prefer a <code>null</value> in case of
   * the parameter missing.
   */
  boolean required() default true;


}

然后写注解的实现方法

package com.cheshangma.operation.wx.configuration;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
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 com.cheshangma.operation.entity.ThirdPartUserEntity;
import com.cheshangma.operation.entity.UserEntity;

import com.cheshangma.operation.wx.annotation.ObjectConvertAnno;
import com.cheshangma.operation.wx.service.ThirdPartUserService;
import com.cheshangma.operation.wx.service.UserService;


@Configuration
public class ObjectConvertResolver
    implements
      HandlerMethodArgumentResolver,
      ApplicationContextAware {
  private static boolean isReloaded = false;
  private static ApplicationContext applicationContext;

  private UserService userService;
  private ThirdPartUserService thirdPartUserService;
  /**
  *
  *判断是否支持要转换的参数类型 
  *
  */
  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    return parameter.getParameterAnnotation(ObjectConvertAnno.class) != null;
  }
  /**
  *当supportsParameter返回true,支持后进行相应的转换 
  *
  */
  @Override
  public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    Object[] paramAnnos = parameter.getParameterAnnotations();
    if (paramAnnos == null || paramAnnos.length == 0) {
      return new Object();
    }
    for (Object anno : paramAnnos) {
      if (!ObjectConvertAnno.class.isInstance(anno)) {
        continue;
      }
      ObjectConvertAnno objectConvertAnno = (ObjectConvertAnno) anno;
      Object object = execute(parameter, webRequest);
      if (objectConvertAnno.required() && object == null) {
        return null;
      }
      return object;
    }
    return new Object();
  }

  private Object execute(MethodParameter methodParameter, NativeWebRequest webRequest) {
    Class<?> paramType = methodParameter.getParameterType();
    if (paramType.equals(UserEntity.class)) {

      return getCurrentUser((HttpServletRequest) webRequest.getNativeRequest());
    } else if (paramType.equals(ThirdPartUserEntity.class)) {
      return getCurrentThirdPartUser((HttpServletRequest) webRequest.getNativeRequest());
    }
    return null;
  }

  /**
   * 获取当前用户
   * 
   * @return
   */
  private UserEntity getCurrentUser(HttpServletRequest request) {
    synchronized (ObjectConvertResolver.class) {
      while (!isReloaded) {
        try {
          ObjectConvertResolver.class.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

      // TODO 这里写业务
      userService = ObjectConvertResolver.applicationContext
          .getBean(com.cheshangma.operation.wx.service.UserService.class);
      return userService.getWeChatCurrentUser(request);
    }
  }

  /**
   * 获取当前登陆的第三方用户
   * 
   * @return
   */
  private ThirdPartUserEntity getCurrentThirdPartUser(HttpServletRequest request) {
    synchronized (ObjectConvertResolver.class) {
      while (!isReloaded) {
        try {
          ObjectConvertResolver.class.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

      // TODO 这里写业务
      thirdPartUserService = ObjectConvertResolver.applicationContext
          .getBean(com.cheshangma.operation.wx.service.ThirdPartUserService.class);
      return thirdPartUserService.getWeChatCurrentUser(request);
    }
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    synchronized (ObjectConvertResolver.class) {
      ObjectConvertResolver.applicationContext = applicationContext;
      isReloaded = true;
      ObjectConvertResolver.class.notifyAll();
    }
  }
}

这里还需要把上面写的操作类加入到WebMvcConfigurerAdapter 中

package com.cheshangma.operation.wx.configuration;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author 
 * @version 
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new ObjectConvertResolver());
  }
}

这里的thirdPartUserService.getWeChatCurrentUser(request);和userService.getWeChatCurrentUser(request);实现差不多,就贴一个的

@Override
  public UserEntity getWeChatCurrentUser(HttpServletRequest request) {
    UserEntity user = null;
    Cookie cookie = CookieUtils.getCookie(request, PRINCIPALCOOKIE_NAME);
    if (cookie == null) {
      return null;
    }
    String cookieValue = cookie.getValue();
    LOG.info("cookie="+cookie.getName()+"="+cookieValue);
    if (cookieValue == null) {
      return null;
    }
    String[] values = cookieValue.split(SPLIT);
    String id = values[0];
    LOG.info("userid:"+id);
    String cookieSHAValue = values[1];
    user = userRepository.findOne(id);
    if (user == null) {
      return null;
    }
    String summary = null;
    try {
      summary = SHACoder.encryptShaB64(user.getId(),user.getId());
    } catch (Exception e) {
      LOG.error(e.getMessage());
      return null;
    }
    if (summary == null || !summary.equals(cookieSHAValue)) {
      return null;
    } else {
      return user;
    }

  }

这样就可以了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值