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

Spring Boot中findById返回null或查询为空时如何返回指定JSON

问题根因

  • 控制器逻辑错误:你直接用petService.getPetById(petId)的返回值构造了ResponseEntity对象,这个对象本身永远不会为null,所以if(matchingPet != null)判断永远为真,哪怕service返回了null,你还是会返回200状态码+null的响应体,同时打印pet found日志。
  • 分层职责错误:Service层只负责业务逻辑查询,ResponseEntity是控制层专属的响应封装类,Service层返回该类型和接口定义的Pet返回值冲突,自然不会生效。
  • 需求不匹配:当前404响应没有返回自定义提示的JSON结构,不符合需求。

修正方案

方案1(推荐:统一响应结构)

1. 新增通用响应封装类

用于统一返回JSON格式,同时承载成功数据和错误提示:

import lombok.Data;
// 无lombok可自行添加getter、setter方法
@Data
public class CommonResult<T> {
    private Integer code;
    private String msg;
    private T data;

    public static <T> CommonResult<T> success(T data) {
        CommonResult<T> result = new CommonResult<>();
        result.setCode(200);
        result.setMsg("查询成功");
        result.setData(data);
        return result;
    }

    public static <T> CommonResult<T> fail(Integer code, String msg) {
        CommonResult<T> result = new CommonResult<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

2. 修正Service层逻辑

直接返回Optional避免空指针,符合JDK8+规范:
PetService.java:

public interface PetService {
    Optional<Pet> getPetById(int petId);
}

PetServiceImpl.java:

@Service
public class PetServiceImpl implements PetService {
    private PetRepository petrepository;

    public PetServiceImpl(PetRepository petrepository) {
        this.petrepository = petrepository;
    }

    @Override
    public Optional<Pet> getPetById(int petId) {
        return petrepository.findById(petId);
    }
}

3. 修正Controller层逻辑

先判断查询结果是否存在,再封装响应:

@GetMapping("{id}")
public ResponseEntity<CommonResult<?>> getPetById(@PathVariable("id") int petId) {
    Optional<Pet> petOpt = petService.getPetById(petId);
    if(petOpt.isPresent()) {
        logger.info("pet found");
        return new ResponseEntity<>(CommonResult.success(petOpt.get()), HttpStatus.OK);
    } else {
        logger.info("pet does not exist");
        return new ResponseEntity<>(CommonResult.fail(404, "未找到对应宠物信息"), HttpStatus.NOT_FOUND);
    }
}

方案2(无封装类快速修正)

不需要新增响应类,直接调整Controller逻辑即可:

@GetMapping("{id}")
public ResponseEntity<?> getPetById(@PathVariable("id") int petId) {
    // 先取Service返回的实体,判断是否为null
    Pet matchingPet = petService.getPetById(petId);
    if(matchingPet != null) {
        logger.info("pet found");
        return new ResponseEntity<>(matchingPet, HttpStatus.OK);
    } else {
        logger.info("pet does not exist");
        // 构造自定义提示的JSON返回
        Map<String, String> errMsg = new HashMap<>();
        errMsg.put("msg", "未找到对应宠物信息");
        return new ResponseEntity<>(errMsg, HttpStatus.NOT_FOUND);
    }
}

该方案下Service层保持原有返回Pet的代码即可,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:27:04