赞
踩
应用:秒杀场景中,避免直接暴露秒杀接口,实现url动态化
实现方法
- 前端页面点击/getPath,获取动态路径path,同时后端存储path
- 获取成功后,将path与秒杀路径拼接,如"/"+path+"/miaosha"
-
- 后端读取动态路径path(@PathVariable),并进行检验
-
- 如果与后端存储的路径匹配,则执行后续步骤,否则抛异常退出
说明
- 秒杀地址动态化可防止秒杀地址直接暴露,用户只能点击按钮触发秒杀请求
- 但是,用户可使用脚本频繁点击按钮,因此需要使用限流措施防止刷接口
***********
dto 层
ResponseResult
- @Data
- public class ResponseResult<T> {
-
- private String code;
- private String status;
- private String message;
- private T data;
- }
***********
util 层
StoreUtil
- public class StoreUtil {
-
- private static final Map<String,String> map=new HashMap<>();
-
- public static void setValue(String key, String value){
- map.put(key, value);
- }
-
- public static String getValue(String key){
- return map.get(key);
- }
-
- public static void deleteKey(String key){
- map.remove(key);
- }
- }
***********
service 层
DynamicUrlService
- @Service
- public class DynamicUrlService {
-
- public String createPath(String userId, String goodId){
- //此处也可验证秒杀开始时间,秒杀开始后返回path
- String key=userId+goodId;
- String value=RandomStringUtils.randomAlphanumeric(20);
- value=DigestUtils.md5DigestAsHex(value.getBytes(StandardCharsets.UTF_8));
-
- StoreUtil.setValue(key,value);
- return value;
- }
-
- public boolean checkPath(String pathKey, String pathValue){
- if (pathKey==null || pathValue==null){
- return false;
- }
-
- synchronized (this){
- if (pathValue.equals(StoreUtil.getValue(pathKey))){
- StoreUtil.deleteKey(pathKey);
-
- return true;
- }
- }
-
- return false;
- }
- }
***********
config 层
WebConfig
- @Configuration
- public class WebConfig implements WebMvcConfigurer {
-
- @Override
- public void addViewControllers(ViewControllerRegistry registry) {
- registry.addViewController("/index").setViewName("index");
- }
- }
***********
controller 层
HelloController
- @RestController
- public class HelloController {
-
- @Resource
- private DynamicUrlService dynamicUrlService;
-
- @RequestMapping("/getPath")
- public ResponseResult<String> getPath(String userId, String goodId){
- if ( (userId==null||userId=="")
- || (goodId==null||goodId=="") ){
- throw new RuntimeException("userId或者goodId不能为空");
- }
-
- String path = dynamicUrlService.createPath(userId,goodId);
-
- ResponseResult<String> result=new ResponseResult<>();
- result.setCode("000000");
- result.setStatus("success");
- result.setData(path);
-
- return result;
- }
-
- @RequestMapping("/{path}/hello")
- public ResponseResult<String> hello(@PathVariable("path") String path,
- String userId, String goodId,
- String name, Integer age){
- System.out.println(userId+" "+goodId);
- System.out.println(path);
-
- String key=userId+goodId;
- if (!dynamicUrlService.checkPath(key,path)){
- throw new RuntimeException("path 检验出错");
- }
-
- System.out.println(name+" "+age);
-
- ResponseResult<String> result=new ResponseResult<>();
- result.setCode("000000");
- result.setStatus("success");
- result.setData(name+" "+age);
-
- return result;
- }
-
- @ExceptionHandler
- public ResponseResult<String> handleException(Exception e){
- ResponseResult<String> result=new ResponseResult<>();
- result.setCode("111111");
- result.setStatus("error");
- result.setMessage(e.getMessage());
-
- return result;
- }
- }
***********
前端页面
index.html
- <!DOCTYPE html>
- <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
- xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <script src="/jquery/jquery-3.6.0.min.js"></script>
- <script src="/layui-v2.6.8/layui/layui.js"></script>
- <link rel="stylesheet" href="/layui-v2.6.8/layui/css/layui.css">
- <script>
- $(function (){
- let path;
-
- $("#btn").click(function (){
- $.get({
- url: "/getPath",
- data: {
- userId: $("#userId").val(),
- goodId: $("#goodId").val()
- },
- success: function (result){
- if (result.code === "000000" ){
- path=result.data;
-
- $.get({
- url: "/"+path+"/hello",
- data: {
- userId: $("#userId").val(),
- goodId: $("#goodId").val(),
- name: "瓜田李下",
- age: 20
- },
- success: function (result){
- if (result.code==="000000"){
- layer.msg(result.data);
- }else {
- layer.msg(result.message)
- }
- }
- })
- }else {
- layer.msg(result.message);
- }
- }
- })
- })
- })
- </script>
- </head>
- <body>
- <div th:align="center">
- <div class="layui-form-item">
- <label class="layui-form-label" style="color: coral;font-weight: bolder">userId</label>
- <div class="layui-input-inline">
- <input type="text" id="userId" required lay-verify="required" placeholder="请输入userId" autocomplete="off" class="layui-input">
- </div>
- </div>
- <div class="layui-form-item">
- <label class="layui-form-label" style="color: coral;font-weight: bolder">goodId</label>
- <div class="layui-input-inline">
- <input type="text" id="goodId" required lay-verify="required" placeholder="请输入goodId" autocomplete="off" class="layui-input">
- </div>
- </div>
- <div class="layui-form-item">
- <div class="layui-input-inline">
- <button id="btn" class="layui-btn">提交</button>
- </div>
- </div>
- </div>
- </body>
- </html>
localhost:8080/index
userId、goodId均为空,点击按钮
userId、goodId不为空,点击按钮
使用任意path,直接访问/{path}/hello
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。