Dart-Aqueduct框架开发(四)
- 2019 年 10 月 6 日
- 筆記
声明:本文首发于微信订阅号:Dart客栈 文章为原创,如需转载请注明出处,并告知作者,谢谢!
1.介绍
这篇文章将详细介绍URL、路由,前几篇有小伙伴私信留言说讲得有点快,感觉跟不上,所以,接下来的文章中,将详细介绍Aqueduct
的相关内容.
2.什么是URL?
每个http
请求都有一个URl,可以作为客户端访问服务器的一个访问路径,例如:http://xxxx.com/image/xxx.jpg
,当客户端请求该路径地址时,服务端将返回对应的图片资源给客户端,URL是Web
应用程序提供的,客户端可以通过web
应用程序提供的URL来操作web
应用程序的资源,例如:数据库中的数据增删改和查询,文件的创建和删除等
3.URL的组成
URL由许多部分组成,其中一部分是可选的,例如https://www.baidu.com/index.html
,当浏览器访问这个URL时,将显示百度的index.html
页面,这个页面包含三个必要组件:scheme(https)
、host(www.baidu.com)
、path(/index.html)
,其中,path
是可选的而且可以是多个,并且Aqueduct
框架只关心path
,也就是Aqueduct
中的访问路由
4.匹配路由
如上一节的代码中:
@override Controller get entryPoint { //定义路由、请求链接等,在启动期间调用 router.route('/queryArticle').linkFunction((request) async{ final query = Query<Article>(context); final List<Article> articles=await query.fetch(); return Response.ok(articles); }); return router; }
当客户端访问的path
为/queryArticle
时,将会匹配到路由,并获取到代码中Response.ok
里面参数的内容,path
可以有多段,路由路径规范为每个段与请求的每个段相匹配,每个段的数量也必须相同,才能访问到,下面是一个反面例子:/queryArticle/1
,这个路径将访问不了上面的资源
路由路径上的变量/:id
路径规范中,可以拥有变量,最经常用于获取唯一标识的资源,例如:/queryArticle/1
,/queryArticle/2
,通常的,我们以:
冒号开头的path
作为变量,添加如下代码,根据id
访问文章
```dart @override Controller get entryPoint { //定义路由、请求链接等,在启动期间调用 router.route('/queryArticle/:id').linkFunction((request) async { final id = request.path.variables['id']; //获取路径上的id变量 if (int.tryParse(id) != null) {//判断是否为int类型 final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id));//查询id对应的文章 final articles = await query.fetchOne();//查询第一条 if(articles!=null){ //判断是否存在 return Response.ok(articles); //查询成功,返回文章 }else{ return Response.ok({"msg":"no exist"});//不存在该文章 } }else{ return Response.badRequest(body:{"msg":"error"});//查询失败,id不是int类型 } }); return router; }
在启动服务器之前,我们插入几条数据到数据库中

然后访问

?很棒!程序都按照我们的预想成功了
可选路径变量/[:id]
或[/:id]
当前,我们的路径在访问文章的时候,我们之前已经有一个访问路径了,现在我们又加了一个,等于代码冗余了,这不是我们想看到的,那么这个时候,可以使用可选路径,当存在id
的时候,就去访问对应的id,当不存在id时,我们就查询所有文章,所以,将之前的代码合并到/queryArticle
路径来,使用中括号
把:id
括起来,说明这个是可选变量,代码如下:
@override Controller get entryPoint { //可选变量[:id] router.route('/queryArticle/[:id]').linkFunction((request) async { final id = request.path.variables['id']; if(id==null){ final query = Query<Article>(context); final List<Article> articles = await query.fetch(); return Response.ok(articles); }else if (int.tryParse(id) != null) { final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id)); final articles = await query.fetchOne(); if(articles!=null){ return Response.ok(articles); }else{ return Response.ok({"msg":"no exist"}); } }else{ return Response.badRequest(body:{"msg":"error"}); } }); return router; }
这样就可以实现了,感兴趣的小伙伴可以运行一下,这里就不一一展示了,路径规范中,可以包含多个可选路径变量,例如:/a/[b/[:c]]
将匹配/a
、/a/b
、a/b/c
,不匹配/a/c
限制路径变量(可使用正则表达式)/:id([0-9]+)
一般的,我们可以使用变量后接括号,把正则表达式括起来/:变量(正则表达式)
,让我们限制一下上面请求的id只能为整数,不匹配将返回404
,然后代码判断部分就可以直接去掉
@override Controller get entryPoint { //正则限制变量/:变量(正则) router.route('/queryArticle/[:id([0-9]+)]').linkFunction((request) async { final id = request.path.variables['id']; if(id==null){ final query = Query<Article>(context); final List<Article> articles = await query.fetch(); return Response.ok(articles); }else{ final query = Query<Article>(context) ..where((a) => a.id).equalTo(int.parse(id)); final articles = await query.fetchOne(); if(articles!=null){ return Response.ok(articles); }else{ return Response.ok({"msg":"no exist"}); } } }); return router; }
匹配路径下的所有路径/*
当我们需要做一系列的匹配时,我们可以在路径的最后一段加上/*
,例如:/user/*
,当请求/user/12
或者/user/12/34
等,都将匹配,一般用于一个大系的URL路由处理
404的处理
一般我们的web
服务器都需要对404做定制处理,下面是自带的404
页面
这样的页面肯定不能满足我们的请求要求,所以需要定制,定制也很简单,Aqueduct
框架为我们在构造路由时,特意留下一个参数设置404
页面,因为我的是API
服务器,所以返回一个json
@override Controller get entryPoint { //edit final router = Router(notFoundHandler: (request) async { Response response=Response.notFound();//404的状态码 response.contentType=ContentType.json;//内容类型 response.body={'code': -1, 'msg': '404'};//内容 await request.respond(response);//把内容相应出去 logger.info("${request.toDebugString()}");//打印日志 }); //路由对象 //edit return router; }
然后再请求404就会看到对应的内容
以上就是这一节的所有内容,如果小伙伴们觉得有收获,不妨点一下再看,让我能看到你跟我一起学习Dart服务器,也是对我写作的一种肯定?!