专栏文章 AOP 切面&自定义注解 用户快速登录

飞狐 · 2019年02月13日 · 最后由 飞狐 回复于 2019年02月18日 · 210 次阅读

这段时间在重写接口测试框架,为了确保对核心业务做全面的校验,因此也增加了 快速登录这块功能

参考官方文档
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop

自定义注解 QuickLogin

package com.hero.common.annotation;

import java.lang.annotation.*;

/**
* @Des: 自定义注解--用户快速登录
* @Auther: 飞狐
* @Date: 2019/2/1
*/

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface QuickLogin {

String name() default "";

String password() default "";
}

AOP切面

支持token过期401时,自动重新登录


@Aspect
@Component
public class UserQuickLoginAspect {

private Log LOG = LogFactory.getLog(UserQuickLoginAspect.class);

@Autowired
private AppConfig appConfig;

@Autowired
private UserInfoService userInfoService;

@Autowired
private UserAccountDAO userAccountDAO;

@Autowired
private CommonUserInfoService commonUserInfoService;

@Before(value = "@annotation(quickLogin)")
public Object doUserLogin(QuickLogin quickLogin) throws Throwable {
String name = quickLogin.name();
String password = quickLogin.password();
Reporter.log("快速登录:" + name + "/" + password);

LocalUserInfo localUserInfo = commonUserInfoService.getLocalUserInfo(name);

if(null == localUserInfo){
return commonUserInfoService.userLoginByPassword(convert2UserLoginRequestInfo(quickLogin));
}

Long userId = localUserInfo.getUserId();

DynamicMethodDataSourceHolder.set(name,userId.toString());

//试下head方法,确定不是401
Result result = userInfoService.headUserProfile(name);

MiniResponse miniResponse = (MiniResponse) result.getRes();

if (miniResponse.getCode() != HttpStatus.OK.value()) {
return commonUserInfoService.userLoginByPassword(convert2UserLoginRequestInfo(quickLogin));
}
return result;

}


private UserLoginRequestInfo convert2UserLoginRequestInfo(QuickLogin quickLogin){
UserLoginRequestInfo userLoginRequestInfo = new UserLoginRequestInfo();
userLoginRequestInfo.setUserName(quickLogin.name());
userLoginRequestInfo.setPassword(quickLogin.password());
userLoginRequestInfo.setAppSource(quickLogin.appSource());
return userLoginRequestInfo;
}


}

ThreadLocal处理,主要减少本地文件读写,直接线程变量中进行处理

/**
* 本地线程缓存变量,存储userId
* Created by huqingen on 2018/6/26.
*/

public class DynamicMethodDataSourceHolder {

public static final ThreadLocal<Map<String,String>> hodler = new ThreadLocal<>();


public static Map<String,String> get(){
return hodler.get();
}

public static void set(Map<String,String> map){
hodler.set(map);
}

public static void set(String key,String value){
Map<String,String> map = hodler.get();
if(map == null){
map = Maps.newHashMap();
}

map.put(key,value);
set(map);
}

public static void clean(){
hodler.remove();
}

}
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 3 条回复 时间 点赞

都用上spring了

具体是在什么时候用啊,什么场景,怎么调用的?

陈大大,主要目的还是解决理解免登处理,代码解耦,不把登录代码写入到对应测试接口中
调用方式:

@Component("userSceneService")
public class UserSceneService{
@Autowired
private UserInfoService userInfoService;

@QuickLogin(name = "18000000005",password = "123456")
public Result checkUserProfile(){

String userName = "18000000005";

Result result = userInfoService.getUserProfileByAnnotation(userName);

MiniResponse miniResponse = (MiniResponse) result.getRes();

HeroAssert.assertEquals(miniResponse.getCode(), HttpStatus.SC_OK,"HTTP状态码为200");

return result;
}
}

新写这套框架,目标是解决核心接口校验(缓存/es/db),及抽离这个校验方法,后续直接用到app自动化上,顺带 锻炼测试童鞋的代码编写能力~纯web页面形式的接口测试,主要写些非核心类的接口

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册