SpringBoot+MQ+Redis+BootStrap 秒杀系统(三) 登录业务之jsr303参数校验+分布式session+异常处理

17 篇文章 0 订阅
8 篇文章 0 订阅

项目地址:https://github.com/wannengdek/spring-boot-seckill

如果项目对您有所帮助,麻烦帮忙点亮小⭐⭐

参数校验+全局异常处理器

1、使用 Vaild 进行检验

依赖:

<!--        自定义参数校验器+全局异常处理器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

在形参前加上@Vaild ,然后在实体类的属性上加上注解。

	@NotNull
	@IsMobile
	private String mobile;
	
	@NotNull
	@Length(min=32)
	private String password;

notNull 的意思就是不为空,isMobile 就是验证是否为电话号码。

2 自定义异常处理

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

	@ExceptionHandler(value=Exception.class)
	//异常拦截
	public Result<String> exceptionHandler(HttpServletRequest request, Exception e){
		e.printStackTrace();
		if(e instanceof GlobalException) {
			GlobalException ex = (GlobalException)e;
			return Result.error(ex.getCm());
		}else if(e instanceof BindException) {
			BindException ex = (BindException)e;
			List<ObjectError> errors = ex.getAllErrors();
			ObjectError error = errors.get(0);
			String msg = error.getDefaultMessage();
			return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
			//将捕捉到的异常信息传递给状态码  显示到前端
		}else {
			return Result.error(CodeMsg.SERVER_ERROR);
		}
	}
}

首先是异常捕获,将捕获到的异常进行处理,然后使用包装类包装成需要的数据返回给后端.

Service 层的login 方法:

 

效果如下:

手机号如果是2 开头会报错

 

分布式Session

现在的服务器基本都是集群,比如用户A登录到了服务器A,session也存放到了服务器A,但当用户使用其他服务,跳转到服务器B时,服务器B没有用户A的登录信息,又让用户登陆一次,这是很不友好的.所以需要解决session一致性问题.

可以使用redis 将session 中的信息存放到redis中,每个服务器需要使用的时候去redis 中获取,也就不会出现session 不一致的问题.

(图片来自于:https://blog.csdn.net/xlgen157387/article/details/79191900)

 

本项目使用的解决方式是: 当用户的登录成功之后将他的相关信息返回到后端,生成token 存放到cookie 中,以后每次访问页面都带着token去访问,而通过解析cookile中的请求头中的token 就可以拿到用户的个人信息,不用去数据库中查询.

大概是这样的一个流程,感觉理解的不是很透彻,还需要加强.

 

使用  ArgumentResolvers 来直接将 User 信息注入到controller 中,方便操作.

@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 接口说明:
     * supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
     * resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
     */

	@Autowired
	MiaoshaUserService userService;

    /**
     *  判断是否为指定对象
     * @param parameter
     * @return
     */
	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		Class<?> clazz = parameter.getParameterType();
		return clazz== MiaoshaUser.class;
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
								  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
		HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);

		String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);

		try {
			String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
			//判断是否有cookie
			if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
//				System.out.println("清除cookie 后没有 cookie 返回null");
				return new GlobalException(CodeMsg.SERVER_ERROR);
			}
			String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
//			System.out.println("判断是否有cookie----resolveArgument");
			return userService.getByToken(response, token);
		}catch (Exception e1){
				return new GlobalException(CodeMsg.SERVER_ERROR);
		}
	}

 

参考:

https://blog.csdn.net/fanrenxiang/article/details/81738634

https://blog.csdn.net/zhangli_wei0403/article/details/84328218

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值