修剪控制器操作中的字符串请求参数

时间:2016-05-04 02:16:05

标签: grails

我正在使用grails 2.4.4应用程序,该应用程序具有一些不在控制器中使用绑定或命令对象的遗留代码,在此应用程序中,请求参数使用其构造函数从控制器操作直接传递到java类。

我们希望从字符串参数中修剪空格(就像Grails默认情况下在绑定时一样)但不使用绑定或命令对象。

也许注入一个克隆版本的params varible但是有修剪值?

你们有没有做过这样的事情?

2 个答案:

答案 0 :(得分:3)

这是我在过滤器中的2.x应用中使用的实现。它通过递归调用方法来支持嵌套对象:

def filters = {
   blankToNullAndTrim(controller: '*', action: '*') {
      before = {
         convertBlanksToNullsAndTrim params
         true
      }
   }
}

private static void convertBlanksToNullsAndTrim(Map<String, Object> map) {
   def keys = map.keySet() as List // copy to avoid ConcurrentModificationException
   for (name in keys) {
      def value = map[name]
      if (value instanceof String) {
         value = value.trim()
         if (value.length() == 0) {
            map[name] = null // have to explicity set to null, not remove
         }
         else {
            map[name] = value // update if trimmed
         }
      }
      else if (value instanceof Map) {
         // empty nested param, e.g. "location":["id":""]
         convertBlanksToNullsAndTrim value
      }
   }
}

这里是等效的实现(包含类型信息,因此您可以使用@GrailsCompileStatic)在升级到Grails 3.x时在拦截器中使用:

boolean before() {
   convertBlanksToNullsAndTrim params
   true
}

private void convertBlanksToNullsAndTrim(Map<String, Object> map) {
   List<String> keys = map.keySet() as List // copy to avoid ConcurrentModificationException
   for (String name in keys) {
      def value = map[name]
      if (value instanceof String) {
         value = value.trim()
         if (value.length() == 0) {
            map[name] = null // have to explicity set to null, not remove
         }
         else {
            map[name] = value // update if trimmed
         }
      }
      else if (value instanceof Map) {
         // empty nested param, e.g. "location":["id":""]
         convertBlanksToNullsAndTrim value
      }
   }
}

答案 1 :(得分:0)

一个选项是在UrlMappings.groovy中使用动态解析变量。例如,如果存在如下映射:

"/airport/status(controller: 'airport', action: 'checkStatus')

并期望请求参数为airportName,然后可以将其重写为:

"/airport/status(controller: 'airport', action: 'checkStatus') {
    airportName = { params.airportName?.trim() }
}

这将确保在修剪实际请求参数params后将任意变量设置为airportName。必须注意使用与请求参数相同的变量名来支持下面的遗留系统。

另一个选项可以是在控制器上使用filter来修剪请求参数。类似的东西:

class UtilityFilters {
    def filters = {
        trim(controller: "airport", action: "*") {
            before = {
                // If immutable then make a copy and edit
                params.airportName = params.airportName?.trim()
                return true
            }
        }
    }
}