例外或无效签入?什么更优雅?

时间:2015-12-23 10:51:39

标签: java

假设我有html表单和控制器来处理该表单。 Controller启动一个服务,它接受2个参数。如果用户从表单中发送空字段,则参数可以为null。

现在......如何处理这种情况?什么更优雅?我更喜欢将此值从控制器传递到服务,而不检查控制器层中的值是否为null。

  

第一种方法 - 检查控制器层的空值

@RequestMapping(method = RequestMethod.POST)
    public String borrowBook(@RequestParam(value = "borrower_id", required = false) Long borrowerId,
            @RequestParam(value = "book_id", required = false) Long bookId){

        if (borrowerId != null && bookId != null)
            borrowService.createBorrow(bookId, borrowerId);

        return "redirect:index.html";
    }
  

第二种方法 - 在cotnroller层将值传递给服务并获取异常

@RequestMapping(method = RequestMethod.POST)
    public String borrowBook(@RequestParam(value = "borrower_id", required = false) Long borrowerId,
            @RequestParam(value = "book_id", required = false) Long bookId){

        try {
            borrowService.createBorrow(bookId, borrowerId);
        } catch(CreateBorrowException e){
            //Do something
        }

        return "redirect:index.html";
    }
  

第三种方法 - 在服务层处理异常,因此控制器实际上并不知道是否发生异常。

Service :
public void createBorrow(Long bookId, Long borrowerId) {
        try {
            Book book = getBookFromId(bookId);
            Borrower borrower = getBorrowerFromId(borrowerId);
            Borrow borrow = new Borrow(book, borrower);
            markBookAsRented(book);
            setBorrowIntoEntities(borrow, book, borrower);
            persistEntities(borrow, book, borrower);
        } catch (Exception e) {

        }
    }
你怎么看?我更喜欢选项2.

3 个答案:

答案 0 :(得分:5)

如果调用者发送空表单正常,那通常是null支票的用例。

如果调用者发送空表单是异常(错误,例如,例外),那通常是允许异常的用例(可能处理它,或允许它传播给调用者。)

哪个更“优雅”是一种风格问题。

请注意,虽然输入try块并不昂贵,但允许抛出异常(昂贵=运行时和[临时]内存开销)。但是,当然,除非你在一秒钟内抛出数十万个例外,否则哪个更快也无关紧要。

答案 1 :(得分:0)

我想建议如下方法:

  • 前端 - 您可以检查javascript以进行空检查。 因为如果您的客户端代码验证相同,那么您可以拥有 更多选择来处理它。而且你可以避免服务器命中。
  • 后端 - 如果您想另外添加服务器端验证 然后将其添加到服务层中,因为所有业务逻辑 应该在服务类;你可以遵循这个。

    1)使用if语句 - 返回boolean值以在控制器中做出决定

    2)只需添加throw为服务类的方法创建借用者异常,并使用try catch块在控制器中处理它。

答案 2 :(得分:0)

我认为这样的选择是非常主观的,重要的是要在整个项目中保持一致,所以应由相关开发人员选择。

那说我会做以下事情:

    @RequestMapping(method = RequestMethod.POST)
    public String borrowBook(@RequestParam(value = "borrower_id", required = false) Long borrowerId,
            @RequestParam(value = "book_id", required = false) Long bookId){
        if(bookId == null || borrowerId == null){
            return "redirect:form.html";             
        }
        int result = borrowService.createBorrow(bookId, borrowerId);
        switch(result){
            case BorrowService.INVALID_ARG:
                return "redirect:form.html";
            case BorrowService.FAILURE:
                return "redirect:error.html";
            case BorrowService.SUCCESS:
                return "redirect:success.html";
            default:
                return "redirect:index.html";
        }              
    }

您还应该重新考虑这些强制性参数的必要性为何。

Service :
    public int createBorrow(Long bookId, Long borrowerId) {            
        Book book = getBookFromId(bookId);
        if(book == null){
            return INVALID_ARG;
        } 
        Borrower borrower = getBorrowerFromId(borrowerId);
        if(borrower == null){
            return INVALID_ARG;
        }
        try {
            Borrow borrow = new Borrow(book, borrower);
            markBookAsRented(book);
            setBorrowIntoEntities(borrow, book, borrower);
            persistEntities(borrow, book, borrower);
        } catch (Exception e) {
            return FAILURE;
        }
        return SUCCESS;
    }