如何在 ServletAPI(Spring MVC)中限制每个用户的请求

Posted

技术标签:

【中文标题】如何在 ServletAPI(Spring MVC)中限制每个用户的请求【英文标题】:How to limit requests per USER in ServletAPI (Spring MVC) 【发布时间】:2015-11-27 13:09:33 【问题描述】:

如何只允许每个用户对具有特定 URL @PathVariable 的 microservice 方法的一个请求。 我的控制器

@RestController
@RequestMapping(value = "/rest/product", produces = "application/json;charset=UTF-8")
public class ProductRestController 
    @Autowired
    ProductService productService;

    @Autowired
    ProductAsm productAsm;

    @RequestMapping(value = "/ID/ID", method = RequestMethod.GET)
    public ResponseEntity<ProductResource> getProductID(@PathVariable("ID") Long ID, @AuthenticationPrincipal User) 

        Product product = productService.getProduct(ID);
        if (product == null)
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);

        return new ResponseEntity<>(productAsm.toResource(product), HttpStatus.OK);
    

例如:

    第一个请求 /rest/product/ID/2231 允许 USER(使用 login="xaxa" ) 第二个请求 /rest/product/ID/2545 允许 USER(使用 login="xaxa" ) 第三个请求 /rest/product/ID/2231 不允许 USER(使用 login="xaxa" )

实现此功能的最佳方式是什么?(我是否必须将此 URL 请求与用户登录数据库中的用户一起保留,或者已经有解决方案)

【问题讨论】:

您必须支持多少个唯一 ID?我有一些想法,但它们的可用性取决于这些数字。另外 - 您是否考虑过某些 ID 的吞吐量 1 的可能性? 一开始有几个id(100-500左右),以后可以增加到5000 不,我没有考虑过这种可能性! 【参考方案1】:

您可以使用 AOP 并实现您自己的方面,该方面将在您的 Rest Endpoint 方法之前调用。

此切入点将读取请求中提供的 ID,并尝试找到与此 ID 对应的锁。然后通常 - 尝试访问资源并可能等待。

实现可以基于 Guava 的 Striped 类 - 至少在开始时是这样。

有几个问题需要考虑:

    可以用一些 LRU 缓存替换条带化,以实现更好的内存管理。 当然,当两个请求同时访问同一个 ID 时,您必须提供同步。 它仅适用于部署在单个节点上的应用程序。 在性能方面这不是很好的方法。根据您的流量,这可能是个问题。

【讨论】:

以上是关于如何在 ServletAPI(Spring MVC)中限制每个用户的请求的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC @Controller中转发或者重定向到其他页面的信息怎么携带和传递(Servlet API对象)HttpServletRequestHttpServletRespose

Spring MVC @Controller中转发或者重定向到其他页面的信息怎么携带和传递(Servlet API对象)HttpServletRequestHttpServletRespose(代码片

Spring MVC 官方文档

Spring MVC学习—MVC的介绍以及Spring MVC的入门案例

Java-24-Spring-10-2-Spring MVC知识点整理

Spring MVC(异步)与 Spring WebFlux