4

I have a question about spring boot. When I want to get the specific user from my database everything is ok but how can I handle the null response (There is no such a user)? I want to handle the return value of null as ResponseEntity but when there is a user with that id I need to return User details. So I could not set return value as ResponseEntity. Here is the screenshot of the problem:

enter image description here

Here is the code:

@GetMapping("get/{id}") public User findById(@PathVariable int id) throws Exception { try { if(userMapper.findById(id) != null) { return userMapper.findById(id); }else { throw new Exception("YOK ULAN YOK"); } }catch (Exception e) { // TODO: Make perfect return new User(-1); } } 

and here is the return value:

{ "email": null, "username": null, "password": null, "name": null, "surname": null, "age": 0, "photoLink": null, "dateOfBirth": null, "phoneNumber": null, "city": null, "country": null, "friendList": null, "plan": null, "id": -1, "planned": false 

}

I don't want to send a -1 user, I want to send a user not found response. How can I handle it?

Thanks,

3 Answers 3

2

the best way is to change method return type from User to ResponseEntity<?>, smth. like:

@GetMapping("get/{id}") public ResponseEntity<?> findById(@PathVariable int id) throws Exception { User user = userMapper.findById(id); if (user == null) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok(user); } 

or using optional:

@GetMapping("get/{id}") public ResponseEntity<?> findById(@PathVariable int id) throws Exception { return Optional.ofNullable(userMapper.findById(id)) .map(ResponseEntity::ok) .orElseGet(ResponseEntity.notFound()::build); } 
Sign up to request clarification or add additional context in comments.

Comments

2

You could use an exception handler to handle these kind of exceptions. To make this work, you could first return an Optional<User> instead of a User. Then you could write your controller as following.

@GetMapping(value = "/get/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<User> findById(@PathVariable int id) { return ResponseEntity .status(HttpStatus.OK) .body(userMapper.findById(id) .orElseThrow(UserNotFoundException::new); } 

The UserNotFoundException is a custom class. You can extend from RuntimeException so the exception becomes unchecked.

public class UserNotFoundException extends RuntimeException {} 

Then you could make an ErrorResponse class. You're free to add the fields you like, but it could look like this:

@Getter @Setter public class ErrorResponse { private int code; private String description; } 

You could then handle this UserNotFoundException in an ExceptionHandler:

@RestControllerAdvice @Slf4j public class ApplicationNameExceptionHandler { @ExceptionHandler public ResponseEntity<ErrorResponse> handleException(UserNotFoundException e) { log.info("User not found"); ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setCode(HttpStatus.NOT_FOUND.value()); errorResponse.setDescription("User not found"); return ResponseEntity .status(HttpStatus.NOT_FOUND) .contentType(MediaType.APPLICATION_PROBLEM_JSON) .body(errorResponse); } 

The advantage of this approach is that you can keep your controllers concise and tidy and all your controller exceptions can be handled in the same class (ApplicationNameExceptionHandler).

Comments

0

We can try to define a exception with reponse status.

@ResponseStatus(value = HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { } 

And then, in your controller, throw this exception

throw new ResourceNotFoundException() 

Or, just set the status of Response directly.
BTW, a better approach is to define our business code to implement it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.