简体   繁体   中英

Different return types for function Java

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.

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