You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

资金追踪服务中如何让登录用户仅查看自身预算及交易数据?

问题描述

我开发了一款资金追踪服务,需要实现登录用户仅能查看自己的预算、交易等专属数据。我尝试在接口中添加Principal参数,通过用户名获取对应数据,但调用接口后未返回任何数据。

相关代码如下:

Controller层代码

@RestController
@RequestMapping("api/v1/budgets")
public class BudgetController {

    private final ModelMapper modelMapper;
    private final BudgetService budgetService;

    public BudgetController(ModelMapper modelMapper, BudgetService budgetService) {
        this.modelMapper = modelMapper;
        this.budgetService = budgetService;
    }

    @GetMapping
    public ResponseEntity<List<BudgetDTO>> getBudgets(Principal principal){

        String loggedInUsername = principal.getName();

        List<BudgetDTO> budgetsDto = budgetService.getBudgetsByCreatedBy(loggedInUsername, 5, 5).stream().map(budget -> modelMapper.map(budget, BudgetDTO.class))
                .collect(Collectors.toList());
        return new ResponseEntity<List<BudgetDTO>>(budgetsDto, HttpStatus.OK);
    }

Repository与Service层代码

@Repository
public interface BudgetRepo extends JpaRepository<Budget, Long> {
    Page<BudgetDTO> findByUserId(Long userId, Pageable page);
}

public ArrayList<BudgetDTO> getBudgetsByCreatedBy(String username, int page, int size) {
        User user = userRepo.getUserByUsername(username);
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "goal");
        Page<BudgetDTO> budgets = budgetRepo.findByUserId(user.getId(), pageable);
        return new ArrayList<BudgetDTO>(budgets.getContent());
    }    

调用接口后无数据返回,截图如下:
未获取到数据


排查与解决方案

1. 修正分页参数逻辑

PageRequest.of(page, size)中的page参数是从0开始计数的,你传入的page=5实际请求的是第6页数据。如果该用户的预算数据不足30条(5页×5条),自然返回空列表。

先测试page=0确认是否能拿到数据:

List<BudgetDTO> budgetsDto = budgetService.getBudgetsByCreatedBy(loggedInUsername, 0, 5)...

2. 修正Repository返回类型

JpaRepository的查询方法默认返回实体类Budget,直接返回Page<BudgetDTO>会因为映射问题导致结果为空。修改Repository方法:

@Repository
public interface BudgetRepo extends JpaRepository<Budget, Long> {
    Page<Budget> findByUserId(Long userId, Pageable page);
}

同时更新Service层,在Service中完成实体到DTO的转换:

public ArrayList<BudgetDTO> getBudgetsByCreatedBy(String username, int page, int size) {
    User user = userRepo.getUserByUsername(username);
    Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "goal");
    Page<Budget> budgets = budgetRepo.findByUserId(user.getId(), pageable);
    return budgets.stream()
                  .map(budget -> modelMapper.map(budget, BudgetDTO.class))
                  .collect(Collectors.toCollection(ArrayList::new));
}

3. 验证数据关联关系

检查Budget实体的userId字段是否与数据库中记录一致,直接执行SQL验证:

SELECT * FROM budget WHERE user_id = (SELECT id FROM user WHERE username = '你的测试用户名');

如果查询为空,说明数据插入时未正确关联用户ID,需要修正数据写入逻辑。

4. 确认用户名获取正确性

在Controller层添加日志打印,确认Principal获取的用户名是当前登录用户的正确用户名:

@GetMapping
public ResponseEntity<List<BudgetDTO>> getBudgets(Principal principal){
    String loggedInUsername = principal.getName();
    System.out.println("当前登录用户:" + loggedInUsername);
    // 后续代码...
}

如果用户名不符,需要检查Spring Security的认证配置是否正确。

5. 添加用户查询空值判断

确保userRepo.getUserByUsername(username)能返回有效用户,避免空指针或无效查询:

public ArrayList<BudgetDTO> getBudgetsByCreatedBy(String username, int page, int size) {
    User user = userRepo.getUserByUsername(username);
    if(user == null) {
        return new ArrayList<>();
    }
    // 后续代码...
}

内容的提问来源于stack exchange,提问作者doneskk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:35:27