我正在开发一个带有RESTful服务的Sping Boot 应用程序,基于JWT的身份验证和前端响应。
我想内置一个计数器来监视唯一的用户请求(例如每天)发送到我的RestController中的某些REST端点,并将当前值存储到数据库中的一列。
具体来说,我想知道每天有多少用户点击了某篇文章(api/articles/{id}
),并将该值绑定到实体。
实体:
@Data
@Builder
@AllArgsConstructor
@RequiredArgsConstructor
@Entity
@Table(name = "Article")
public class Article{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "message_id", unique = true, nullable = false)
private Long id;
@Column(name = "visits")
private Long visitCounter;
...
}
控制器:
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
private AppUserService userService;
private ArticleService articleService ;
@Autowired
public ArticleController (AppUserService userService, ArticleService articleService ) {
this.userService = userService;
this.articleService = articleService;
}
@GetMapping(value = "/{id}")
public ResponseEntity<Article> getArticleById(@PathVariable(value = "id") Long articleId) {
Article article = articleService .getArticleById(articleId);
if(article == null) {
return ResponseEntity.notFound().build();
}
articleService.countVisit(); //???
return ResponseEntity.ok().body(article);
}
}
...
有什么想法可以实现这样的事情吗?
1条答案
按热度按时间pftdvrlh1#
假设您有应用程序范围的bean ArticleCountService。服务应该有一个
Map<String, Set<String>>
用于计数器。关键是文章路径(或id或其他标识文章的东西)。该值是用户的集合(例如IP地址来标识唯一用户,您可以从 HttpServletRequest 获得)。在23:59:999,您将获得Map数据并创建一个新的空Map。这是最简单的解决方案,但它可能会影响内存。
最方便的方式是在DB中存储一些东西。例如ARTICLE_ID、USER_ID(IP)、VISIT_DATE
并且每天一次聚合数据(昨天的过时行可以在计算之后被删除)。