2

是否存在可以从服务(或其他非控制器方法)引发的异常或其他东西,这些异常或其他东西会中断当前的响应处理并向用户返回 404?

在 Django 世界中,有get_object_or_404一个引发了Http404具有这种效果的异常。我正在写服务;如果该服务确定用户无法访问所请求的对象(在这种情况下它尚未发布),我希望它触发 404 并停止剩余的执行。目标是让调用服务的控制器 DRY 并且不总是重复def obj = someService.getSomething(); if (obj) {} else { render status: 404}调用。

摘要:
在 Django 中,我可以在任何时候引发 aHttp404以停止请求处理并返回 404。在 Grails 中是否有等效或方法可以做到这一点,而不是来自控制器?

4

3 回答 3

4

创建一个像 com.my.ResourceNotFoundException 这样的异常类,然后从你想要的任何地方(控制器或服务)抛出它。

创建一个控制器,如下所示:

class ErrorController {

    def error404() {
        response.status = HttpStatus.NOT_FOUND.value()
        render([errors: [[message: "The resource you are looking for could not be found"]]] as JSON)
    }
}

然后在您的 UrlMappings.groovy 配置文件中添加一个条目,该条目将使用此控制器操作处理该类型的异常。将“500”指定为模式意味着它将捕获 500 个错误(例如您抛出的 ResourceNotFoundException 将导致的错误),如果异常与该类型匹配,它将使用指定的控制器和操作。

"500"(controller: "error", action: "error404", exception: ResourceNotFoundException)
于 2014-06-19T13:55:46.337 回答
4

在控制器中,您可以将响应的状态设置为您喜欢的任何代码。

    response.status = 404

您还可以render文档status中的-一起使用:

// render with status code
render(status: 503, text: 'Failed to update book ${b.id}')

您可以让委托给服务的控制器在调用服务方法之前执行此操作,或者您可以让服务向控制器返回状态代码。

于 2013-07-29T23:19:45.817 回答
0

@doelleri 提到了渲染状态代码可以做什么。

下面显示了一种可以在控制器中实现 DRYness 的“不那么时髦”的方式。但同样,如果您想将 try catch 块移动到实用程序,您可以实现更多目标。

//Custom Exception
class CustomException extends Exception{
    Map errorMap

    CustomeException(Map map, String message){
        super(message)
        this.errorMap = map
    }
    ....
}

//service
def getSomethingGood(){
    ....
    ....
    if(something bad happened){
        throw new CustomException([status: HttpStatus.NOT_FOUND.value, 
                                   message: "Something really got messed up"], 
                                   "This is a custom Exception")
        //or just return back from here with bad status code 
        //and least required data
    }
    ......
    return goodObj
}

def getSomething(){
    def status = HttpStatus.OK.value
    def message
    try{
        def obj = getSomethingGood()
        message = "success value from obj" 
        //or can also be anything got from obj  etc
    } catch(CustomException c){
        status = c.errorMap.status
        message = c.errorMap.message
    }

    [status: status, message: message]
}

//controller
def obj = someService.getSomething()
render(status: obj.status, text: obj.message)

另请注意,当您处理已检查的异常时,事务不会在服务层中回滚。还有其他事情要做,我认为这超出了这个问题的范围。

于 2013-07-30T00:23:27.313 回答