栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Egg.js自定义插件(xml解析器)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Egg.js自定义插件(xml解析器)

在学习EggJs企业级web开发框架时,Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,Egg 的插件机制有很高的可扩展性,一个插件只做一件事(比如 Nunjucks 模板封装成了 egg-view-nunjucks、MySQL 数据库封装成了 egg-mysql)。Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低。

文档分析

自己需要开发eggjs的插件就需要根据官方提供的文档进行学习,按照统一的开发约定进行开发。是不是看完官方文档还是一头雾水,不知道从何下手,或者你在网上搜索的内容都是一模一样的。

官方文档关键信息

  1. 插件没有独立的 router 和 controller。这主要出于几点考虑:

    • 路由一般和应用强绑定的,不具备通用性。

    • 一个应用可能依赖很多个插件,如果插件支持路由可能导致路由冲突。

    • 如果确实有统一路由的需求,可以考虑在插件里通过中间件来实现。

  2. 插件需要在 package.json 中的 eggPlugin 节点指定插件特有的信息:

    • {String} name - 插件名(必须配置),具有唯一性,配置依赖关系时会指定依赖插件的 name。

    • {Array} dependencies - 当前插件强依赖的插件列表(如果依赖的插件没找到,应用启动失败)。

    • {Array} optionalDependencies - 当前插件的可选依赖插件列表(如果依赖的插件未开启,只会 warning,不会影响应用启动)。

    • {Array} env - 只有在指定运行环境才能开启,具体有哪些环境可以参考运行环境。此配置是可选的,一般情况下都不需要配置。

    {
      "name": "egg-rpc",
      "eggPlugin": {
        "name": "rpc",
        "dependencies": [ "registry" ],
        "optionalDependencies": [ "vip" ],
        "env": [ "local", "test", "unittest", "prod" ]
      }
    }

  3. 插件没有 plugin.js:

    • eggPlugin.dependencies 只是用于声明依赖关系,而不是引入插件或开启插件。

  4. 包括了 path 和 package 两种加载模式

    • config/plugin.js 中通过 path 来挂载插件。

    // config/plugin.js
    const path = require('path');
    exports.ua = {
      enable: true,
        path.join(__dirname,'../lib/plugin/egg-xml-par')
    };
    • package.json 中声明对 egg-ua 的依赖。config/plugin.js 中修改依赖声明为 package 方式。

    // config/plugin.js
    exports.ua = {
      enable: true,
      package: 'egg-xml-par',
    };

搭建简单的开发环境

安装eggjs基础脚手架

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0):

$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i

启动项目进行测试:

$ npm run dev
$ open http://localhost:7001

新建插件环境

  1. 新建插件文件夹lib (插件所有的配置,代码都在这里面)

  1. 我们是做一个解析xml请求的中间件插件,所有需要搭建下图的结构

. lib
├── plugin
│   ├── egg-xml-par (插件npm名)
    |   ├── package.json (插件名称等配置)
    |   ├── app.js (中间件配置)
    |
    |────── app 
    |       ├── middleware 
    |           ├── xml-par.js(插件处理代码) 
    |
    |────── config 
            ├── config.default.js(插件需要的配置文件)  
 

配置插件基础信息

Egg 是通过 eggPlugin.name 来定义插件名的,只在应用或框架具备唯一性

//lib/plugin/egg-xml-par/package.json
{
  "name": "egg-xml-par",
  "eggPlugin": {
    "name": "XmlPar",
    "version": "1.0.0"
  }
}

将插件加入中间件

在 app.js 中将中间件插入到合适的位置(例如:下面将 xmlPar中间件放到 bodyParser 之前)

//lib/plugin/egg-xml-par/app.js
const assert = require('assert');
​
module.exports = app => {
  // 将 xmlPar 中间件放到 bodyParser 之前
  const index = app.config.coreMiddleware.indexOf('bodyParser');
  assert(index >= 0, 'bodyParser 中间件必须存在');
  app.config.coreMiddleware.splice(index, 0, 'xmlPar');
};

写插件核心代码

//lib/plugin/egg-xml-par/app/middleware/xml-par.js
'use strict';
​
const parse = require('co-body');
const {xml2js} = require('xml-js');
​
module.exports = options => {
  // 获取插件配置 //lib/plugin/egg-xml-par/config/config.default.js
  const xmlTypes = options.xmlTypes;
​
  return async function xmlPar(ctx, next){
    try {
      const res = await parseBody(ctx);
      ctx.request.body = 'parsed' in res ? res.parsed : {};
      if(ctx.request.rawBody === undefined){
        ctx.request.rawBody = res.raw
      }
    } catch (error) {
      ctx.logger.warn(error)
    }
​
    await next();
  }
​
  async function parseBody(ctx){
    if(ctx.request.is(xmlTypes)){
      var body = await parse.text(ctx.request);
      ctx.logger.info(body);
      const xmlContent = xml2js(body);
      return {
        raw : body,
        parsed : xmlContent.elements[0]
      }
    }
    return {}
  }
};

//lib/plugin/egg-xml-par/config/config.default.js
exports.xmlPar = {
  xmlTypes:[
    'text/x-xml',
    'application/xml',
    'application/x-xml'
  ]
}

Egg.js使用自定义插件
  • package 是 npm 方式引入,也是最常见的引入方式

  • path 是绝对路径引入,如应用内部抽了一个插件,但还没达到开源发布独立 npm 的阶段,或者是应用自己覆盖了框架的一些插件

  • 关于这两种方式的使用场景,可以参见渐进式开发。

// config/plugin.js
const path = require('path');
exports.mysql = {
  enable: true,
  path: path.join(__dirname,'../lib/plugin/egg-xml-par')
};

取消egg.js自带解析器与关闭csrf验证

// config/config.default.js 
config.security = {
    csrf: {
      enable: false
    }
  }
​
  config.bodyParser = {
    enable: false
  }

完整项目结构

运行测试

因为接口定义未post,为了方便这里需要关闭csrf验证

// config/config.default.js 
config.security = {
    csrf: {
      enable: false
    }
  }

未使用插件

发现返回结果没有显示

使用插件测试

记得要关闭默认的解析

// config/config.default.js 
 config.bodyParser = {
    enable: false
  }

其他说明

开发其他插件原理类似,希望看完该内容你有点收获

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/301300.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号