美文网首页DartWeb
Dart-Aqueduct框架开发(四)

Dart-Aqueduct框架开发(四)

作者: rhyme_lph | 来源:发表于2019-09-19 23:09 被阅读0次

    上一篇

    声明:本文首发于微信订阅号:Dart客栈,微信后台回复05164获取本篇源码
    文章为原创,如需转载请注明出处,并告知作者,谢谢!

    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/ba/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服务器,也是对我写作的一种肯定🙏!

    下一篇

    相关文章

      网友评论

        本文标题:Dart-Aqueduct框架开发(四)

        本文链接:https://www.haomeiwen.com/subject/gyfhuctx.html