项目中,每个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;
}
}
这样就可以了.