You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mojolicious::Lite中能否使用->to()实现控制器请求转发?

解决Mojolicious::Lite中路由转发控制器404的问题

看起来你的问题出在控制器命名空间和路由映射不匹配上,Mojolicious没找到你定义的bar方法,所以才会尝试去渲染模板(这就是日志里找不到route/bar.html.ep的原因)。

问题根源

你定义的控制器包名是Route::Controller::Route,但你在路由里用的是->to('Route#bar')。Mojolicious默认会按照$app->controller_namespace + :: + 控制器名的规则去查找控制器类:

  • 对于Mojolicious::Lite应用,默认的controller_namespace是main(或者你的Lite应用的匿名类命名空间),所以它会尝试找main::Route这个类,而不是你写的Route::Controller::Route,自然找不到对应的bar方法。

解决方法(任选其一即可)

方法1:修正控制器包名,适配默认命名空间

把你的控制器包名改成Route(比如放在lib/Route.pm里):

package Route;
use Mojo::Base 'Mojolicious::Controller';

sub bar {
  my $self = shift;
  $self->render(json => { hello => 'simone' });
}

1;

然后在你的Lite应用代码开头加上use lib 'lib';(确保能找到lib目录下的控制器),路由保持不变:

use Mojolicious::Lite;
use lib 'lib';

(get '/x')->to('Route#bar');
get '/y' => sub { my $c = shift; $c->render(text => 'here') } => 'y';

app->start;

方法2:在路由里指定完整的控制器类名

如果你想保留现有的Route::Controller::Route包名,直接在to()里写完整的类名即可:

(get '/x')->to('Route::Controller::Route#bar');

这样Mojolicious会直接定位到你定义的控制器类,不需要依赖默认命名空间。

方法3:修改应用的控制器命名空间

在Lite应用里设置controller_namespace为你的控制器所在的父命名空间,这样Route#bar就能映射到Route::Controller::Route->bar:

use Mojolicious::Lite;

app->controller_namespace('Route::Controller');

(get '/x')->to('Route#bar');
get '/y' => sub { my $c = shift; $c->render(text => 'here') } => 'y';

app->start;

测试一下,访问http://localhost:3000/x应该就能正常返回{"hello":"simone"}了。

内容的提问来源于stack exchange,提问作者simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:24:59