简体   繁体   中英

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?

I'm using a bit of a personalized security back-end due to the nature of the app and was trying out how to implement a few simple error returns in my REST API controller. It's simple enough to do in a html page controller like I have in the following:

@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;
    }
}

I can easily just redirect it to the unauthorized page that I made since I'm returning the string value here. However, when I go to a REST API it's not as simple:

@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; 
    }

You can have a ControllerAdvice which handles exceptions and their HTTP return code. Then you can annotate a method in it the following way for example:

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

This will return a 404 code every time it encounters a NoSuchEntityException (custom exception). So you can throw such an exception when you check if an entity is null. You can use the same thing for 401 or any other HTTP code as well.

One way to do this.

    @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); 
    }

You can create custom exceptions within your application for this scenario like BagelNotFoundException and UnauthorizedException. Both these custom exception classes can extend Exception class or more specific classes from java exception hierarchy. You can annotate these custom exception classes with @ResponseStatus annotation to provide the http status code that should be sent in the response.

Next, you need to throw the objects of these exceptions within your controller.

Once this exception is thrown, an exception handler should be present within your application to take care of these exceptions. The same can be defined using @ControllerAdvice and @ExceptionHandler within your custom exception handler classes.

This way you'll be able to send appropriate response to the client, and the client application needs to redirect the user to error pages based on the response code received.

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM