【问题标题】:What belongs to the Controller-layer, what to the Service-layer?什么属于Controller层,什么属于Service层?
【发布时间】:2017-08-13 02:51:29
【问题描述】:

我有一个简单的 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));
}

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

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

【问题讨论】:

  • 不久前,我在一家大型汽车制造商的一个大项目中工作。我们有控制器层、服务层和 DAO 层(数据访问对象 - 用于查询数据库)。逻辑是:控制器接收请求,服务执行操作并在必要时调用 DAO,然后将结果返回给控制器。 DAO 访问数据库并执行查询。控制器层必须非常轻巧,控制器只需委托给服务并加载视图。 DAO 执行查询,而服务使用来自控制器的数据完成所有剩余的工作。
  • 在这个简单的例子中,如果你需要一些业务逻辑,你只需要User user = userService.findOne(id);,你应该像你说的那样实现服务......
  • 好的。这意味着控制器应该什么都不做,只接收请求并将其发回。谢谢你们两个:)

标签: java spring rest spring-boot spring-rest


【解决方案1】:

服务类

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 类

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

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

【讨论】:

  • 我不同意服务层设置if(user == null) { ...} ,因为有时您需要接收用户空值(我不知道整个上下文),您应该在控制器中进行此控制层。
【解决方案2】:

问问自己:如果我想为不同的视图/传输/协议呈现结果,需要改变什么?这属于控制器。

Controller 层中的代码应仅与将 Service 层之间的业务输入/输出映射到视图/传输/协议(视情况而定)有关。这可能(也可能不)包括将业务数据映射到 JSON(您的业务/服务层直接使用 JSON 或类似文件并非不合理)、XML、HTML 或任何您的内容类型(对于 HTTP)。

虽然您的控制器可能感觉很轻巧,但请记住 Spring 对控制器的支持完成了大部分工作 - 将这样一个“简单”控制器视为您的框架识别并挂起所有较重的、锅炉的锚点 -板,代码关闭,对您有利。

【讨论】:

    【解决方案3】:
     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.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-04
      • 2023-03-12
      • 2011-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      相关资源
      最近更新 更多