如果你有不同的方法,基本上只有一行不同,有没有办法通过创建一个方法使其干燥。
示例:
def showA( ) {
def instance
try {
instance = A.findById( params.id )
} catch ( Exception e ) {
def message = "Error while retrieving details for the given id ${ params.id }, $e"
log.error message
responseAsJson( 400, "Invalid id", message )
return false
}
return checkAndRender(instance, params.id);
}
def showB( ) {
def instance
try {
instance = B.findByBId( params.BId )
} catch ( Exception e ) {
def message = "Error while retrieving details for the given id ${ params.id }, $e"
log.error message
responseAsJson( 400, "Invalid id", message )
return false
}
return checkAndRender(instance, params.id);
}
那么,是否有办法制作一个方法并简单地作为参数传递:
或者改为传递SQL语句会更好吗?
基于@dmahapatro评论,我想出了以下内容:
def showA( ) {
def clos = {id -> A.findByAId( id ) }
return findAndShow(clos, params.AId, params )
}
def showB( ) {
def clos = {id -> B.findByBId( id ) }
return findAndShow(clos, params.BId, params )
}
def findAndShow(Closure closure, def id, def p)
{
def instance
try {
instance = closure(id)
}
catch ( Exception e ) {
def message = "Error while retrieving instance details for the given id ${ id }, $e"
log.error message
responseAsJson( 400, "Invalid Id", message )
return false
}
return checkAndRender(instance, id);
}
只剩下的问题是:
如何绕过警告:
[ApiController]中的[findAndShow]动作接受参数 输入[groovy.lang.Closure]。接口类型和抽象类类型 不支持作为命令对象。该参数将被忽略。
def findAndShow(Closure closure, def id, def p)
答案 0 :(得分:1)
如果您想要DRY代码,首先要担心的是定义更好的异常处理。在任何地方尝试捕获代码来处理对客户端的响应都不是很严重,如果将数据访问代码放在服务中,则可以从中抛出异常并使用全局控制器来捕获错误并处理响应。 E.g:
class ErrorController {
def serverError() {
if (request.format == 'json') {
//Code for handling errors in json request, request.exception stores the data about the exception.
} else {
//Code for handling errors in non-json request, e.g:
render(view: 'error', model: [msg: 'Something went wrong']) //add an error view for this
}
}
}
如果您愿意,还可以为其他类型的错误添加处理程序(403,404等)
添加到UrlMappings.groovy
"500"(controller: "error", action: "serverError")
现在,您可以使用新的错误处理和反射重构代码:
控制器:
class MyController {
def myService
def show() {
def result = myService.myFind(params.className,params.id)
render result as JSON //Render stuff
}
}
服务:
import grails.util.Holders
class MyService {
def myFind(String className, Long id) {
def result = Holders.getGrailsApplication().getDomainClass('com.mypack.'+ className).findById(id)
if(!result) {
throw new ServiceException('really descriptive and usefull error msg')
}
}
}
我定义了一个ServiceException类,所以我可以使用instanceOf运算符在我的ErrorController中为它添加自定义逻辑。