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
相关产品推荐
相关产品推荐

