如果数据库查询在 Spring boot webapp REST API 控制器中返回空对象,如何发送 401 作为未授权用户和 404?

How to send a 401 as unauthorized user and a 404 if a database query returned a null object in a Spring boot webapp REST API controller?

由于应用程序的性质,我正在使用一些个性化的安全后端,并且正在尝试如何在我的 REST API 控制器中实现一些简单的错误 returns .在 html 页面控制器中做起来很简单,就像我在下面做的那样:

@Controller
public class HomeController {

    @Autowired
    private UserService userService;

    @GetMapping("/home.html")
    public String home(Model model) {
        String redirect = "home";

        if(!userService.getCurrentUser().isCanAccessService()) {
            redirect = "unauthorized";
        }       
        return redirect;
    }
}

我可以很容易地将它重定向到我创建的未经授权的页面,因为我在这里返回字符串值。但是,当我进入 REST API 时,它并不那么简单:

@RestController
public class bagelController {

    @Autowired
    private bagelService bagelService;

    @Autowired
    private UserService userService;

    @GetMapping("/rest/bagel/search")
    public Bagel searchBagel (@RequestParam(value = "bagel", required = false) String bagel, 
            @RequestParam(value = "bagelInd", required = false, defaultValue = "1") int bagelInd) {

        Bagel bagel;
        if(!userService.getCurrentUser().isBagelEditAccess()) {
            bagel = null;
            // I want to return a 401 or direct to my unathorized page if I get an invalid user here.
        }
        else {
            bagel = bagelService.getbagel(bagel, bagelInd);
            // if my bagel object returns null, I want to return a 404 or direct to a 404 not
               found page here.
        } 
        return bagel; 
    }

您可以有一个 ControllerAdvice 来处理异常及其 HTTP return 代码。然后你可以用下面的方式在其中注释一个方法,例如:

@ExceptionHandler(NoSuchEntityException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)

这将在每次遇到 NoSuchEntityException(自定义异常)时 return 一个 404 代码。所以你可以在检查实体是否为空时抛出这样的异常。您也可以对 401 或任何其他 HTTP 代码使用相同的东西。

您可以在应用程序中为这种情况创建自定义异常,例如 BagelNotFoundException 和 UnauthorizedException。这两个自定义异常 classes 都可以从 java 异常层次结构扩展异常 class 或更具体的 classes。您可以使用 @ResponseStatus 注释对这些自定义异常 class 进行注释,以提供应在响应中发送的 http 状态代码。

接下来,您需要在您的控制器中抛出这些异常的对象。

一旦抛出此异常,您的应用程序中就应该存在一个异常处理程序来处理这些异常。可以在自定义异常处理程序 classes.

中使用 @ControllerAdvice 和 @ExceptionHandler 定义相同的内容

这样您就可以向客户端发送适当的响应,客户端应用程序需要根据收到的响应代码将用户重定向到错误页面。

希望对您有所帮助!

一种方法。

    @GetMapping("/rest/bagel/search")
    public ResponseEntity<Bagel> searchBagel (@RequestParam(value = "bagel", required = false) String bagel, 
            @RequestParam(value = "bagelInd", required = false, defaultValue = "1") int bagelInd) {

        Bagel bagel = null;
        if(!userService.getCurrentUser().isBagelEditAccess()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        else {
            bagel = bagelService.getbagel(bagel, bagelInd);
            if(bagel == null) { 
              return ResponseEntity.notFound().build();
            }
        } 
        return ResponseEntity.ok(bagel); 
    }