grails - Grails 3.1.16 拦截器不过滤方法
问题描述
我正在尝试使用 Grails 拦截器来匹配具有特定 HTTP 方法的特定 uri。但是,尽管我将 Grails 版本从 3.1.1 升级到了3.1.16,但 match 方法的方法参数被忽略了,该问题应该得到修复。
我的代码的简化版本是:
@GrailsCompileStatic
class MyInterceptor {
int order = HIGHEST_PRECEDENCE
MyInterceptor () {
match(uri: '/api/domain/*', method: 'PUT')
match(uri: '/api/domain/*', method: 'DELETE')
match(uri: '/api/domain/*', method: 'POST')
}
}
使用以下拦截器测试:
@TestFor(MyInterceptor)
class MyInterceptorSpec extends Specification {
@Unroll
def "it matches '#method #uri'"() {
when: "A request matches the interceptor"
withRequest(uri: uri, method: method)
then:"The interceptor does match"
interceptor.doesMatch()
where:
uri | method
'/api/domain/1' | 'PUT'
'/api/domain/1' | 'POST'
'/api/domain/1' | 'DELETE'
}
@Unroll
def "it does not match '#method #uri'"() {
when:
withRequest(uri: uri, method: method)
then:
!interceptor.doesMatch()
where:
uri | method
'/api/domain' | 'GET'
'/api/domain/1' | 'GET' // failing test
}
}
如何确保拦截器仅匹配给定 HTTP 方法的 uri?
解决方案
在 Grails 中默认情况下是不可能的。
查看 UrlMappingMatcher 的代码我们可以看到,当我们用 uri 定义匹配规则时,方法部分被忽略了:
@Override
Matcher matches(Map arguments) {
if(arguments.uri) {
uriPatterns << arguments.uri.toString()
}
else {
controllerRegex = regexMatch( arguments, "controller")
actionRegex = regexMatch( arguments, "action")
namespaceRegex = regexMatch( arguments, "namespace")
methodRegex = regexMatch( arguments, "method")
}
return this
}
@Override
Matcher excludes(Map arguments) {
if(arguments.uri) {
uriExcludePatterns << arguments.uri.toString()
}
else {
def exclude = new MapExclude()
exclude.controllerExcludesRegex = regexMatch( arguments, "controller", null)
exclude.actionExcludesRegex = regexMatch( arguments, "action", null)
exclude.namespaceExcludesRegex = regexMatch( arguments, "namespace", null)
exclude.methodExcludesRegex = regexMatch( arguments, "method", null)
excludes << exclude
}
return this
}
但是,您可以创建 UrlMappingMatcher 的子类,即使在定义了 uri 时也会考虑该方法,并使用它而不是 Interceptor 中的常规方法:
// in MyInterceptor.groovy
Matcher match(Map arguments) {
// use your own implementation of the UrlMappingMatcher
def matcher = new MethodFilteringUrlMappingMatcher(this)
matcher.matches(arguments)
matchers << matcher
return matcher
}
推荐阅读
- python-3.x - 在另一个目录python3中导入一个模块
- ios - 升级到 Monterey macOS 后在所有应用程序上完成 xcode 构建时出现“Runners预期退出”错误
- python - 调用时项目不会增加
- javascript - 这个函数将使用 Ramda 组合做什么
- c++ - 将代码移至类时,Arduino NeoPixel 代码行为异常
- reactjs - aws amplify 将自定义域添加到存储
- google-data-studio - 为什么不能将日期导入 Google 数据洞察连接器?
- r - 使用模板将扩展文件传递给 grunt 中的外部脚本
- android - 在循环内更新 showdialog/alertdialog
- visual-studio-code - VSCode natvis 处理某些变量,但不处理相同模板类型的其他变量