Grails 服务呼叫控制器?

Grails 服务呼叫控制器?,grails,Grails,Grails使得控制器调用服务和将请求转发到另一个控制器都非常容易 因此,假设您有一个这样的服务方法 List<String> updateNames() { ... } 列表更新名称(){ ... } 您可以很容易地从任何控制器调用它 我想知道,如果您有一个边缘案例,您意识到您的服务方法中存在验证问题。您不想将异常抛出回控制器,因为这不是真正的异常情况。但是您不能将错误消息从服务返回给调用的控制器,因为这意味着您必须使用一些包装器对象,而不是一个漂亮的列表 在这些情况下

Grails使得控制器调用服务和将请求转发到另一个控制器都非常容易

因此,假设您有一个这样的服务方法

List<String>  updateNames() {
   ...
}
列表更新名称(){
...
}
您可以很容易地从任何控制器调用它

我想知道,如果您有一个边缘案例,您意识到您的服务方法中存在验证问题。您不想将异常抛出回控制器,因为这不是真正的异常情况。但是您不能将错误消息从服务返回给调用的控制器,因为这意味着您必须使用一些包装器对象,而不是一个漂亮的列表

在这些情况下,您是否可以让服务将服务器端转发到另一个控制器上,从而向用户返回错误响应


谢谢。

服务以这种方式不知道web/http请求上下文。我不会讨论会话或请求范围的服务如何模糊这一行,因为它仍然不适用于您所询问的内容。另外,您真的不想让您的服务知道它正在处理web/http请求,因为您希望分离责任并有一个好的/干净的设计

那么,回到你的问题上来。这正是从服务引发异常并让控制器处理该异常结果的情况。如果它是实例上的验证错误,那么您应该能够访问控制器中实例的errors集合(当然,前提是它是服务的输入)

作为有关服务异常的旁注。堆栈跟踪的填充成本很高。这在Grails中更是如此,因为有很多作品在工作。我强烈建议,如果您打算从您的服务中引发自己的业务逻辑异常,您可以覆盖异常上的fillInStackTrace方法,以避免这一成本

以下是一个例子:

package com.example

class MyBusinessException extends RuntimeException {

    List<String> argList = []

    public MyBusinessException (String message, List<String> args){
        super(message)

        argList = args
    }

    public MyBusinessException (String message){
        super(message)
    }

    /**
    * Don't fill in the stack trace because we want things to be faster.
    **/
    @Override
    public Throwable fillInStackTrace() {
        // do nothing
        return this
    }
}
package.com.example
类MyBusinessException扩展了RuntimeException{
列表argList=[]
公共MyBusinessException(字符串消息、列表参数){
超级(讯息)
argList=args
}
公共MyBusinessException(字符串消息){
超级(讯息)
}
/**
*不要填充堆栈跟踪,因为我们希望事情更快。
**/
@凌驾
公共可丢弃的fillInStackTrace(){
//无所事事
还这个
}
}

服务以这种方式不知道web/http请求上下文。我不会讨论会话或请求范围的服务如何模糊这一行,因为它仍然不适用于您所询问的内容。另外,您真的不想让您的服务知道它正在处理web/http请求,因为您希望分离责任并有一个好的/干净的设计

那么,回到你的问题上来。这正是从服务引发异常并让控制器处理该异常结果的情况。如果它是实例上的验证错误,那么您应该能够访问控制器中实例的errors集合(当然,前提是它是服务的输入)

作为有关服务异常的旁注。堆栈跟踪的填充成本很高。这在Grails中更是如此,因为有很多作品在工作。我强烈建议,如果您打算从您的服务中引发自己的业务逻辑异常,您可以覆盖异常上的fillInStackTrace方法,以避免这一成本

以下是一个例子:

package com.example

class MyBusinessException extends RuntimeException {

    List<String> argList = []

    public MyBusinessException (String message, List<String> args){
        super(message)

        argList = args
    }

    public MyBusinessException (String message){
        super(message)
    }

    /**
    * Don't fill in the stack trace because we want things to be faster.
    **/
    @Override
    public Throwable fillInStackTrace() {
        // do nothing
        return this
    }
}
package.com.example
类MyBusinessException扩展了RuntimeException{
列表argList=[]
公共MyBusinessException(字符串消息、列表参数){
超级(讯息)
argList=args
}
公共MyBusinessException(字符串消息){
超级(讯息)
}
/**
*不要填充堆栈跟踪,因为我们希望事情更快。
**/
@凌驾
公共可丢弃的fillInStackTrace(){
//无所事事
还这个
}
}

服务以这种方式不知道web/http请求上下文。我不会讨论会话或请求范围的服务如何模糊这一行,因为它仍然不适用于您所询问的内容。另外,您真的不想让您的服务知道它正在处理web/http请求,因为您希望分离责任并有一个好的/干净的设计

那么,回到你的问题上来。这正是从服务引发异常并让控制器处理该异常结果的情况。如果它是实例上的验证错误,那么您应该能够访问控制器中实例的errors集合(当然,前提是它是服务的输入)

作为有关服务异常的旁注。堆栈跟踪的填充成本很高。这在Grails中更是如此,因为有很多作品在工作。我强烈建议,如果您打算从您的服务中引发自己的业务逻辑异常,您可以覆盖异常上的fillInStackTrace方法,以避免这一成本

以下是一个例子:

package com.example

class MyBusinessException extends RuntimeException {

    List<String> argList = []

    public MyBusinessException (String message, List<String> args){
        super(message)

        argList = args
    }

    public MyBusinessException (String message){
        super(message)
    }

    /**
    * Don't fill in the stack trace because we want things to be faster.
    **/
    @Override
    public Throwable fillInStackTrace() {
        // do nothing
        return this
    }
}
package.com.example
类MyBusinessException扩展了RuntimeException{
列表argList=[]
公共MyBusinessException(字符串消息、列表参数){
超级(讯息)
argList=args
}
公共MyBusinessException(字符串消息){
超级(讯息)
}
/**
*不要填充堆栈跟踪,因为我们希望事情更快。
**/
@凌驾
公共可丢弃的fillInStackTrace(){
//无所事事
还这个
}
}

服务以这种方式不知道web/http请求上下文。我不会讨论会话或请求范围的服务如何模糊这一行,因为它仍然不适用于您所询问的内容。另外,你真的