控制器
控制器在 Finch 中封装了请求处理逻辑。控制器是一个继承 Controller 的类,通过 rq 访问当前请求对象。
基本结构
import 'package:finch/finch_route.dart';
class HomeController extends Controller {
Future<String> index() async {
return rq.renderView(path: 'home/index');
}
}
在路由中使用控制器:
final homeController = HomeController();
FinchRoute(
key: 'root',
path: '/',
methods: Methods.ONLY_GET,
index: homeController.index,
),
rq 对象
rq(request 的缩写)是每个控制器方法中可用的核心对象。它提供对请求数据、响应方法、会话、Cookie、语言等的访问。
响应方法
| 方法 | 描述 |
|---|---|
rq.renderView(path: '...') |
渲染 Jinja 模板。路径相对于 widgetsPath |
rq.renderData(data: {...}) |
返回 JSON 响应 |
rq.renderError(status: 404) |
发送 HTTP 错误响应 |
rq.renderString(text: '...') |
返回纯文本或 HTML |
rq.redirect(url: '...') |
重定向到 URL |
rq.renderNotFound() |
返回 404 |
渲染模板
Future<String> index() async {
return rq.renderView(
path: 'home/index', // 相对于 widgetsPath 的路径,无扩展名
params: {
'title': '首页',
'user': currentUser,
},
);
}
返回 JSON
Future<String> apiUser() async {
var id = rq.getParam('id');
var user = await UserModel().find(id: id);
return rq.renderData(data: user?.toJson() ?? {});
}
读取请求数据
// 查询/表单参数
var name = rq.get<String>('name', def: '');
var age = rq.get<int>('age', def: 0);
// 路径参数 (/users/{id})
var id = rq.getParam('id');
// 原始 JSON body
var body = await rq.getBodyAsJson();
// 上传的文件
var file = rq.getFile('avatar');
请求属性
rq.method // 'GET', 'POST', …
rq.path // '/users/42'
rq.ip // 客户端 IP 地址
rq.headers // Map<String, List<String>>
rq.isJson // Content-Type 是否为 application/json
rq.currentLanguage // 当前语言代码
向模板传递数据
除了 renderView 中的 params 之外,还可以在 FinchRoute 定义中为整个路由指定参数:
FinchRoute(
key: 'root',
path: '/',
params: {'siteName': 'Finch 演示'},
index: homeController.index,
),
路由级数据与 renderView 中的控制器级数据合并。
HTTP 错误
// 发送 403 Forbidden
return rq.renderError(status: 403, message: '禁止访问');
// 发送 500 Internal Server Error
return rq.renderError(status: 500);