什么属于Controller层,什么属于Service层?

What belongs to the Controller-layer, what to the Service-layer?

我有一个简单的 Spring-Boot Restful 应用程序。我有一个控制器层和一个存储层,但没有服务层。让我向您展示我的控制器方法之一:

@RequestMapping(value = "users/{id}", method = RequestMethod.GET)
public Resource<UserResource> get(@PathVariable Long id) throws NotFoundException {
    log.info("Invoked method: get with ID: " + id);
    log.warn("Searching for user with ID " + id);
    User user = userRepository.findOne(id);
    if (user == null){
        log.error("Unexpected error, User with ID " + id + " not found");
        throw new NotFoundException("User with ID " + id + " not found");
    }
    log.info("User found. Sending request back. ID of user is " + id);
    return new Resource<UserResource>(getUserResource(user));
}

因为我没有服务层,我的控制器为我做业务逻辑。现在我想实现服务层。我的控制器应该/不应该做什么?

我的服务层(我现在想实现)是否应该完成所有工作而我的控制器只将请求委托给服务层?

服务Class

public class UserService {
     public User findUser(String id){
          log.info("Invoked method: get with ID: " + id);
          log.warn("Searching for user with ID " + id);
          User user = userRepository.findOne(id);
          if (user == null){
            log.error("Unexpected error, User with ID " + id + " not found");
            throw new NotFoundException("User with ID " + id + " not found");
          }
         log.info("User found. Sending request back. ID of user is " + id);
         return user;
     }
}

API class

    @RequestMapping(value = "users/{id}", method = RequestMethod.GET)
    public Resource<UserResource> get(@PathVariable Long id) throws    NotFoundException {
          return new Resource<UserResource>(userService.findUser(id));
    }

添加通用异常处理程序 NotFoundException 以重定向到正确的错误页面。

问问自己:如果我想为不同的 view/transport/protocol 呈现结果,需要更改什么?那属于控制器。

Controller 层中的代码应该只与 Service 层到 view/transport/protocol 之间的映射业务 input/output 有关(视情况而定)。这可能(或可能不)包括将业务数据映射到 JSON(您的 business/service 层直接与 JSON 或类似层一起工作并非不合理),XML,HTML,或任何您的内容类型(对于 HTTP)。

虽然您的控制器可能感觉很轻,但请记住,Spring 对控制器的支持完成了大部分工作 - 将这样的 "simple" 控制器视为您的锚点框架识别并挂起所有较重的样板代码,对您有利。

 public class UserService{

     public User findUser(String id){
          log.info("Invoked method: get with ID: " + id);
          log.warn("Searching for user with ID " + id);
          User user = userRepository.findOne(id); 
          log.info("User found. Sending request back. ID of user is " + id);
          return user;
      }
    }




@RequestMapping(value = "users/{id}", method = RequestMethod.GET)
public Resource<UserResource> get(@PathVariable Long id) throws NotFoundException {
      User user = userService.findUser(id)
      if (user == null){
           log.error("Unexpected error, User with ID " + id + " not found");
           throw new NotFoundException("User with ID " + id + " not found");
      }
      return new Resource<UserResource>(getUserResource(user));
 }
}

基于@Jai 的响应,唯一的区别是 if,因为有时你需要接收一个用户 null

public void anotherMethod(@PathVariable Long id){
    User user = userService.findOne(id);
    if(user == null) {
        //in this case I don't want to throw NotFoundException and make some other logic like create the user for example.
    }
}