1.隐藏地址实现思路
/**
* 秒杀地址隐藏
* 先去请求接口获得秒杀地址
* 1.接口带上PathVarible参数
* 2.添加生成地址的接口,
* 3.秒杀收到请求的时候先验证Pathvarible
*
*点击秒杀---触发onclick事件---请求服务端地址getMashaPath()
* -----发送ajax get请求请求,请求参数为goodsId,url=“/miaosha/path”
* -----controller层的getMiaosha调用miaoshaservic
* String path = create.MiashoPath(user,gooodsId,)
* ---path的组成是:UUID+123456
* ----path 保存在redis中key为userId+"_"+goodsId
*
* 前端接收成功:获得返回地址
* 调用 doMiaosha(path)
*
* doMiaosha(path) 的流程:
* 发送ajax 请求地址:url="/miaosha/"+path+"do_miaosha"
* --->sucess: getMiaoshaRessult($("#goodsId").val());
* --->error:显示错误“客户端”
*
* controller:
* miaosha方法 requestMapping请求地址“/{path}/do_miaosha”
* path 与redis 中获得path对比
* 如果比对不成功则返回比对失败
*/
1.1立即秒杀
<button class="btn btn-primary btn-block" type="button" id="buyButton"onclick="getMashaPath()">立即秒杀</button>
1.2 getMashpath 方法
function getMashaPath() {
$.ajax({
url:"/miaosha/path",
type:"GET",
data:{
goodsId:$("#goodsId").val(),
},
success:function(data){
if(data.code != null){
console.log("data+"+data.data);
doMiaosha(data.data)
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.msg("客户端请求有误");
}
});
}
1.3 controller 层:返回秒杀地址
@ResponseBody
@RequestMapping(value = "/path")
public Result<String> getMiaoshaPath(HttpServletRequest request, MiaoshaUser user, @RequestParam(value = "goodsId") Long goodsId){
logger.info("test");
user=getMiaoshauser(request);
if(user.getId()==null){
return Result.error(CodeMsg.SESSION_ERROR);
}
logger.info("test2"+user);
String path = miaoshaService.createMiaoshaPath(user, goodsId);
return Result.success(path);
}
1.4miaoshaService 获得UUID ,并保存redis 中。
@Override
public String createMiaoshaPath(MiaoshaUser user, long goodsId) {
String str= UUID.randomUUID().toString();
redisService.set(AccessKey.key,""+user.getId()+"_"+goodsId,str);
return str;
}
1.5 前端访问domiaosha :
function doMiaosha(path){
$.ajax({
url:"/miaosha/"+path+"/do_miaosha",
type:"POST",
data:{
goodsId:$("#goodsId").val(),
path:path
},
success:function(data){
if(data.code == 0){
//window.location.href="/miaoshaorder_detail.htm?orderId="+data.data.id;
getMiaoshaResult($("#goodsId").val());
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.msg("客户端请求有误");
}
});
}
1.6 controller :domiaosha 获取redis中的UUID 是否与前端的一致。
@RequestMapping("/{path}/do_miaosha")
@ResponseBody
public Result<Integer> do_miaosha(HttpServletRequest servletRequest,Model model,
@RequestParam (value = "goodsId") Long goodsId,
@RequestParam(value="path" )String path){
Cookie[] cookies = servletRequest.getCookies();
if(cookies==null||cookies.length==0){
return null;
}
String token=null;
for (int i = 0; i <cookies.length ; i++) {
String name = cookies[i].getName();
if(name.equals("token")){
token=cookies[i].getValue();
break;
}
}
MiaoshaUser user = redisService.get(MiaoshaUserKey.token, token, MiaoshaUser.class);
model.addAttribute("user",user);
if(user==null){
return Result.error(CodeMsg.SESSION_ERROR);
}
//验证地址是否相同
boolean checPath = miaoshaService.checPath(user, goodsId, path);
if(!checPath){
return Result.error(CodeMsg.MIAOSHA_PATH_ERROR);
}
//内存标记减少redis 访问
//查询是否有库存
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
if(goods.getStockCount()<=0){
return Result.error(CodeMsg.MIAO_SHA_OVER) ;
}
//查询当前用户是否有订单
//判断是否已经秒杀到了
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
if(order != null) {
model.addAttribute("errmsg", CodeMsg.REPEATE_MIAOSHA.getMsg());
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
//放入队列
MiaoshaMessge miaoshaMessge =new MiaoshaMessge();
miaoshaMessge.setGoodsId(goodsId);
miaoshaMessge.setUser(user);
miaoshaMessge.setUserId(user.getId());
mqSender.sendMiaoshaMessage(miaoshaMessge);
return Result.success(0);//返回0 表示排队中
// OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
// if(orderInfo==null){
//
// model.addAttribute("errmsg", CodeMsg.MIAO_SHA_ERROR.getMsg());
// return "miaosha_fail";
// }
// model.addAttribute("orderInfo", orderInfo);
// model.addAttribute("goods", goods);
// return "order_detail";//跳转到秒杀订单。
}
service层:执行对比
@Override
public boolean checPath(MiaoshaUser user, long goodsId, String path) {
String oldPath = redisService.get(AccessKey.key, "" + user.getId() + "_" + goodsId,String.class);
return path.equals(oldPath);
}