整合spring boot + Mybatis (二)登录及异常处理

参数校验及异常处理

思路:接入层会校验参数时,如果错误,抛业务异常Biz Exception。通过@RestControllerAdvice进行异常处理。比如login接口,

@GetMapping("login")
public DataResponse<LoginUserResp> login(String username, String password) {
	if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
		throw new BizException(ErrorCode.PARAM_ERROR.getErrorCode(), "username or password cannot be null");
	}
	return userService.login(username, password);
}	

拦截并处理异常

@RestControllerAdvice
public class GlobalExceptionHandler {

	@ExceptionHandler(value = BizException.class)
	public DataResponse<BizException> handldBizException(BizException ex) {
		System.out.println("---------------- Handle biz exception --------------- ");
		ex.printStackTrace();
		return DataResponse.buildFail(ex);
	}

	@ExceptionHandler(value = Exception.class)
	public DataResponse<BizException> handldException(Exception ex) {
		System.out.println("---------------- Handle exception --------------- ");
		ex.printStackTrace();
		return DataResponse.buildFail(ex.getMessage());
	}
}

登录

建一个用户表,SQL如下:

CREATE TABLE `t_user` (
	`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
	`username` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '名称',
	`password` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '密码',
	`phone` VARCHAR(50) NULL DEFAULT '0' COMMENT '手机号',
	`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
	`modify_user` INT(11) NOT NULL DEFAULT '0' COMMENT '修改人',
	`modify_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
	`is_delete` TINYINT(2) NOT NULL DEFAULT '0' COMMENT '是否删除',
	PRIMARY KEY (`id`)
)
COMMENT='临时测试表,无意义,要随时删除'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=100000
;

Dao,Service 这两层的代码就不写了。代码里做了个限制,Service给Controller返回结果时,也统一用DataResponse封装。

application.properties 配置数据库

spring.datasource.url=jdbc:mysql://xxxx:端口/dbname
spring.datasource.username=xxxx
spring.datasource.password=xxxxxxxxxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

登录时,通过AES 加密,生成一个Token,然后通知注册拦截器HandlerInterceptor对接口进行拦截,解析token成功后,ThreadLocal存储和读取登录用户信息。
拦截器代码如下

@Component
public class UserInterceptor implements HandlerInterceptor {
	@Autowired
	UserDao userDao;
	
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {        
        String token = getToken(request);
        if (StringUtils.isEmpty(token)) {//未传token
            throw new BizException(ErrorCode.USER_NOT_LOGIN);
        }
        int userId = TokenUtil.parseToken(token);
        UserBo loginUser = userDao.getUserById(userId);
        if ( loginUser == null) {
        	throw new BizException(ErrorCode.USER_NOT_LOGIN);
        }
        ThreadLocalUtil.setLoginUser(loginUser);
//        request.getSession().setAttribute("loginUser", loginUser);
        return true;
    }
    
    private String getToken(HttpServletRequest request) {
    	String token = request.getHeader("token");
    	if (StringUtils.isEmpty(token)) {
    		token = request.getParameter("token");//url直接传参
    	}
    	return token;
    }
    
}

存取登录用户

public class ThreadLocalUtil {
    private static ThreadLocal<UserBo> loginUser = new ThreadLocal<>();

    public static UserBo getLoginUser() {
        return loginUser.get();
    }

    public static void setLoginUser(UserBo u) {
        loginUser.set(u);
    }
    
}

后面传到github去,把本地缓存也搞一下

你可能感兴趣的:(spring,java,mybatis,mysql)