Mojolicious路由如何根据URL查询参数匹配对应处理方法?
Mojolicious同路径不同查询参数匹配不同控制器方法的解决方案
问题原因
Mojolicious路由默认仅匹配请求的路径部分,你写在路由规则中的
?file=:file&name=:name属于查询参数,不会被路由规则识别,因此你定义的两个路由实际匹配的路径都是/api/get_data。路由匹配遵循从上到下的顺序,先定义的路由优先级更高,因此两种场景都会触发process_forms方法。
实现方案
Mojolicious路由内置了查询参数匹配条件功能,你可以通过两种常用方式实现需求:
方案1:使用内置requires方法匹配查询参数(推荐)
Mojolicious 8.0及以上版本内置了query_params路由条件,你只需要调整路由定义顺序,给带参数的路由更高优先级即可:
my $route = $r->any('/api')->to('API#'); # 带指定查询参数的路由优先定义 $route->get('/get_data') # 要求请求必须同时携带file、name两个查询参数 ->requires( query_params => ['file', 'name'] ) ->to('#submit_forms'); # 无指定参数的普通路由放在后面 $route->get('/get_data')->to('#process_forms');
如果需要对参数值做正则校验,也可以修改requires配置:
->requires( query_params => { file => qr/^[a-zA-Z0-9_]+\.\w+$/, # 限制file参数值符合文件名格式 name => qr/^[a-z]{3,10}$/ # 限制name参数为3-10位小写字母 } )
方案2:使用under做前置判断(适合复杂校验场景)
如果你的参数校验逻辑比较复杂,可以用under定义路由前置拦截分支:
my $route = $r->any('/api')->to('API#'); # 定义前置判断分支 my $has_file_name_params = $route->under('/get_data' => sub { my $c = shift; # 同时存在file和name参数时进入该分支后续路由 return 1 if defined $c->param('file') && defined $c->param('name'); # 不满足条件则继续匹配后续普通路由 return 0; }); # 满足条件的请求走submit_forms $has_file_name_params->get('/')->to('#submit_forms'); # 不满足条件的请求走process_forms $route->get('/get_data')->to('#process_forms');
内容的提问来源于stack exchange,提问作者brainoverflow
相关产品推荐
相关产品推荐

