服务是否可以返回404响应?

时间:2013-07-29 22:45:46

标签: grails grails-2.0 grails-services

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

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

要点:
在Django中,我可以在任何时候提出Http404来停止请求处理并返回404.在控制器的Grails NOT 中是否存在等效或方法?

3 个答案:

答案 0 :(得分:4)

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

    response.status = 404

您还可以将renderstatus - from the docs一起使用:

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

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

答案 1 :(得分:4)

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

创建一个类似下面的控制器:

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)

答案 2 :(得分:0)

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

您可以在控制器中实现干燥的“不那么时髦”的方式如下所示。但是,如果您想将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)

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