I'm using Spring Boot with Data JPA.
I have the following code.
A User Class with name and an informative message.
class UserResponse{
private String name;
private String message;
}
User JPA Repository which finds userBy id;
interface UserRepository{
Optional<User> findUserById(String id);
}
User Service which invokes repo and set message if user not found
class UserService(){
UserResponse user = new UserResponse();
public UserResponse getUserById(String userId){
Optional<User> useroptional = userRepository.findById(userId);
if(userOptional.isPresent()){
user.setName(userOptional.get().getName());
}else{
user.setMessage("User Not Found");
}
}
UserController has to set proper HTTP status code as per the message.
class UserController(){
public ResponseEntity<UserResponse> getUserById(String id){
UserResponse user = userService.getUserById(id);
HttpStatus status = OK;
if(!StringUtils.isEmpty(user.getMessage())){
status = NOT_FOUND;
}
return new ResponseEntity<>(user,status);
}
}
The problems I have faced is inorder to set proper status code in controller layer I have to inspect user message,which i didn't like. Is there anyway we can create a control flow for Success and Failure cases.
Say One Return type and flow for Success scenario and vice-versa. I know Scala has this feature with Either keyword. Is there any alternate in Java ? Or any other approach I can use to handle this better...
One approach would be returning RepsonseEntity in service layer itself with proper status code but setting status code is controller's Responsibility is what I felt.
In case of failure you can throw custom Exception
with proper message. Then you can catch it in @ControllerAdvice
. I'll add an example in a moment.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> exception(MyCustomException e) {
return new ResponseEntity(e.getMessage(), HttpStatus.NotFound);
}
}
In one @ControllerAdvice
one could have more methods listening for different Exception
s. Custom Exception can hold whatever you want - it's a normal class - so you can return ResponseEntity
of whatever you want.
For example:
@Transactional(readOnly = true)
@GetMapping("/{id}")
public ResponseEntity<?> getUserById(@PathVariable("id") String userId) {
return userRepository.findById(userId)
.map(user -> ResponseEntity.ok().body(user))
.orElse(new ResponseEntity<>(/* new ErrorMessage */, HttpStatus.NOT_FOUND))
}
For 'not found' response you have to create an error message object and return it to client.
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.