nodejs+koa2 实现模仿springMVC框架

koa2-MVC架构

---------后端技术做前端

环境:nodejs

开发工具:Visual Studio Code(下文简称:VSC)

环境安装,工具安装及中文自行百度,环境调整好后开始进入正题。

1、在硬盘上新增一个文件夹,打开VSC,点击‘添加工作区文件夹',如果没有欢迎‘使用页面',点击--文件--新建窗口,效果如下图:

2、添加vsc调试。Shift+ctrl+p,输入框内输入:launch.json

选择刚刚的文件夹

3、目录结构

从低到高one by one

3-1、package.json

{
 "name": "koa2mcv",
 "version": "1.0.0",
 "description": "Hello Koa 2 example with MVC",
 "main": "app.js",
 "scripts": {
  "start": "node app.js"
 },
 "author": "baba",
 "dependencies": {
  "koa": "2.11.0",
  "koa-router": "8.0.8",
  "koa-bodyparser": "4.3.0",
  "koa-static-plus": "0.1.1",
  "koa-view": "2.1.3",
  "koa-jwt": "4.0.0",
  "koa-log4": "2.3.2",
  "jsonwebtoken": "8.5.1",
  "nunjucks": "3.2.1",
  "mime": "2.4.5",
  "mz": "2.7.0"
 }
}

参数介绍:name项目名称、version版本号、description项目描述、main项目启动文件、scripts启动快捷设置,author作者,dependencies第3方中间件名称及版本。

3-2、app.js

//启动服务
require('./config/init').startServer();

启动相关配置,封装到config/init.js中,启动文件直接引用即可。

3-3、views存放html页面

3-4、static存放静态文件,css,js,font等

3-5、src存放业务控制,类似于springMVC中的controller、service。

3-6、config存放核心配置文件。

3-6-1、init.js项目核心。

异常友好处理

function handler(){
 return async (ctx, next) => {

  const start = new Date().getTime();

  var urlReq=ctx.request.url;
  if(urlReq !== '/favicon.ico'){

   console.log(`请求地址:${ctx.request.method} ${urlReq}`);
   try {

    let params =Object.assign({}, ctx.request.query, ctx.request.body);

    if(config["token"].excludeUrl.indexOf(urlReq) == -1 && !tokenFunction.varifyToken(params.token)){
     ctx.status =401;
    }else{
     await next();
    }
   } catch (error) {
    ctx.status=401;
    console.log(`错误!无法获取token参数`);
   }finally{

     let err={};
     if(!ctx.status){
      err.status = 500;
     }else if(ctx.status==200){
      return;
     }else{
      err.status = ctx.status;
     }

     switch(err.status){
      case 404:
       err.url = config["server-name"]+'/static/public/404.html';
       err.message="资源不存在!";
       break;
      case 401:
       err.url = config["server-name"]+'/static/public/10000.html';
       err.message="登陆失效!请重新登陆!";
       break;
      case 500:
       err.url = config["server-name"]+'/static/public/500.html';
       err.message="系统内部错误!";
       break;
     }

     switch(ctx.request.type){
      case 'application/json':
       ctx.type = 'application/json';
       ctx.body = {errorCode:err.errorCode,message: err.message}
       break;
      default:

       ctx.type = 'text/html';
       ctx.redirect(err.url);
       break;
     }
   }
  }
  const ms = new Date().getTime() - start;
  console.log(`请求消耗时间: ${ms}ms`);
 }
}

路由配置

function controller(){

 const router = new koaRouter({
  prefix: config["server-name"]
 });

 function findJsonFile(rootpathStr){

  fs.readdirSync(rootpathStr).forEach(function (item, index) {

   let fPath = path.join(rootpathStr,item);

   let stat = fs.statSync(fPath);

   if(stat.isDirectory() === true) {
    findJsonFile(fPath);
   }

   if (stat.isFile() === true&&fPath.endsWith('.js')) {

    var mapping = require(fPath);
    for (var url in mapping) {
     if (url.startsWith('GET ')) {
      router.get(url.substring(4), mapping[url]);
     } else if (url.startsWith('POST ')) {
      router.post(url.substring(5), mapping[url]);
     } else if (url.startsWith('PUT ')) {
      router.put(url.substring(4), mapping[url]);
     } else if (url.startsWith('DELETE ')) {
      router.del(url.substring(7), mapping[url]);
     }
     console.log(`注册 URL: ${url}`);
    }
   }
  });
 }

 findJsonFile(rootpath + 'src');
 return router.routes();
}

视图渲染

function templating() {
 var
  autoescape = config['templating-autoescape'] === null ? true : config['templating-autoescape'],
  noCache = config['templating-noCache'] === null ? false : config['templating-noCache'],
  watch = config['templating-watch'] === null ? false : config['templating-watch'],
  throwOnUndefined = config['templating-throwOnUndefined'] === null ? false :config['templating-throwOnUndefined'],
  env = new nunjucks.Environment(
   new nunjucks.FileSystemLoader(rootpath+'views', {
    noCache: noCache,
    watch: watch,
   }), {
    autoescape: autoescape,
    throwOnUndefined: throwOnUndefined
   });
 if (config['templating-filters'] != null) {
  for (var f in config['templating-filters']) {
   env.addFilter(f, config['templating-filters'][f]);
  }
 }
 return async (ctx, next) => {
  ctx.render = function (view, model) {
   ctx.response.body = env.render(view, Object.assign({}, ctx.state || {}, model || {}));
   ctx.response.type = 'text/html';
  };
  await next();
 };
}

启动构建

function startServer(){

 const app = new koa();

 app.use(koaStaticPlus(rootpath+'static', {
  pathPrefix: config["server-name"]+'/static'
 })
 );

 app.use(koaBodyParser());

 app.use(handler());

 app.use(templating());

 app.use(controller());

 app.listen(config["server-port"]);

}

3-6-2、config.js项目参数配置。

module.exports ={
 'server-name':'/koa',
 'server-port':3000,
 "templating-noCache":true,
 "templating-watch":true,
 "templating-autoescape":null,
 "templating-throwOnUndefined":null,
 "templating-filters":null,
 "token":{
  "excludeUrl":[
  "/koa/login",
  "/koa/dologin"
  ],
  "timeout":1000 * 60 * 60 * 24 * 7,
  "secret":"jiaobaba"
 }

}

3-6-3、token.js项目token相关方法封装。

const jwt = require("jsonwebtoken");
const config = require('./config');
/**
 * 创建token的方法
 */
let createToken = (data)=>{
 let obj = {};
 //存入token的数据
 obj.data = data || {};
 //token的创建时间
 obj.ctime = (new Date()).getTime();
 return jwt.sign(obj,config["token"].secret);
}
/**
 * 验证token是否合法的方法
 * @param {*} token
 */
let varifyToken = (token)=>{
 let result = null;
 try{
  let {data,ctime,expiresIn} = jwt.verify(token,config["token"].secret);
  let nowTime = (new Date()).getTime();
  if(nowTime-ctime<config["token"].timeout){
   result = data;
  }
 }catch(error){

 }
 return result;
}

module.exports = {
 createToken,
 varifyToken
};

3-6-4、logger.js项目日志配置文件。

4、项目结构构建结束,接着引入所有依赖包,在终端中执行‘npm install' ,会下载package.json中dependencies所有包,以及这些包所依赖的包。

执行后项目结构会增加两个文件

5、编写测试用例,在src下新建hello.js。

//token
const token = require('../config/token');

var fn_hello = async (ctx, next) => {
 var name = ctx.params.name;
 ctx.response.body = `<h1>Hello, ${name}!</h1>`;
};

var fn_index = async (ctx, next) => {
 ctx.response.body = `<h1>Index</h1>
  <form action="/koa/signin" method="post">
   <p>Name: <input name="name" value=""></p>
   <p>Password: <input name="password" type="password"></p>
   <p><input type="submit" value="Submit"></p>
  </form>`;
};

var fn_signin = async (ctx, next) => {
 var
  name = ctx.request.body.name || '',
  password = ctx.request.body.password || '';
 console.log(`登陆名: ${name}, 密码: ${password}`);
  ctx.response.body = `<h1>Welcome, ${name}!</h1><br/>you token:<br/>${token.createToken({user: name,password: password})}`;

};

module.exports = {
 'GET /hello/:name': fn_hello,
 'GET /login': fn_index,
 'POST /dologin': fn_signin
};

6、启动项目

启动成功

测试访问:http://127.0.0.1:3000/koa/login

输入值获取token

先不用带token进行访问

拦截成功

带上token 进行访问

测试成功!

到此这篇关于nodejs+koa2 实现模仿springMVC的文章就介绍到这了,更多相关nodejs+koa2 springMVC内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • nodejs6下使用koa2框架实例

    koa2里面使用ES7的语法,如async.await所以需要运行在node7.6之后:但在node7.6之前也可以利用babel是的koa2可以运行. 首先项目中安装babel,和babel的几个模块: npm install babel babel-register babel-preset-env --save 然后在入口文件中引入'babel-register'模块 require('babel-register'); 而后引入业务代码: require('./server.js');

  • nodejs中Express与Koa2对比分析

    知会上看到有个问题 <Express会被Koa2取代吗?> .刚好对Express.koa有点小研究,于是简单回答了一下. 1.先说结论 目前没有看到Express会被koa2取代的迹象. 目前来说,Express的生态更成熟,入门门槛相对较低.从npm上的下载热度来说,两者的差距还较大,Express的月下载量约为koa2的40倍. 不过koa2的亮点足够吸引人,生态也开始变得完善. 2.从使用门槛来说 从使用上来说,Express对初学者更有好些,对着官网修修改改改就能做点东西出来. ko

  • nodejs之koa2请求示例(GET,POST)

    GET 请求 在 koa 中,GET请求获取请求数据request对象中的 query 方法和 querystring 方法, query方法返回的是格式化好的参数,querystring 方法返回的是请求字符串.废话不多说,直接上代码 app.js 中添加如下代码: router.get('/getData', async (ctx,next) => { // 从上下文的request对象中获取 let request = ctx.request; let req_query = reques

  • nodejs+koa2 实现模仿springMVC框架

    koa2-MVC架构 ---------后端技术做前端 环境:nodejs 开发工具:Visual Studio Code(下文简称:VSC) 环境安装,工具安装及中文自行百度,环境调整好后开始进入正题. 1.在硬盘上新增一个文件夹,打开VSC,点击'添加工作区文件夹',如果没有欢迎'使用页面',点击--文件--新建窗口,效果如下图: 2.添加vsc调试.Shift+ctrl+p,输入框内输入:launch.json 选择刚刚的文件夹 3.目录结构 从低到高one by one 3-1.pack

  • 使用jQuery.form.js/springmvc框架实现文件上传功能

    使用的技术有jquery.form.js框架, 以及springmvc框架.主要实现异步文件上传的同时封装对象,以及一些注意事项. 功能本身是很简单的,但是涉及到一些传递参数类型的问题.例如:jquery的ajax方法与jquery.form.js中的ajaxSubmit方法的参数,具体细节将在下一篇博客中分享. 重点: html表格三要素: action="fileUpload/fileUpload" method="post" enctype="mul

  • SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的

    json作为一种轻量级的数据交换格式,在前后台数据交换中占据着非常重要的地位.Json的语法非常简单,采用的是键值对表示形式.JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序,也可以从服务器端程序传递json格式的字符串给前端并由前端解释.这个字符串是符合json语法的,而json语法又是 javascript语法的子集,所以javascript很容易解释它,而且

  • SpringMVC框架实现图片上传与下载

    本文实例为大家分享了SpringMVC框架实现图片上传与下载的具体代码,供大家参考,具体内容如下 1.新建一个Maven webapp项目,引入需要用的夹包,pom.xml文件的依赖包如下: <dependencies> <!-- 用于生成图片的缩略图 --> <dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId>

  • idea创建springMVC框架和配置小文件的教程图解

    这个框架主要还是思想,之后,,,还是创建项目好了, 1.新建一个项目 新建一个maven,并且选择webapp类型. 2.点击next选项 这里面的两个选项可以随便填,但是Artifactid一般是项目名,第一个可以是自己定义的名称了, 3.继续点next 在这我们可以添加name=archetypeCatalog,internal,可以在创建项目的时候快一点,3.创建好了项目之后就把我创建的一个小案例放上了 1.创建项目的流程01.引入需要的pom文件节点02.web.xml文件中配置核心控制

  • Java SpringMVC框架开发之数据导出Excel文件格式实例详解

    在平时的开发中,我们会经常遇到这样一个需求,要在页面通过一个『导出』按钮把查询出的数据导出到 Excel 表格中.本文即为实现上述需求的一个小实例. 环境配置 jar包 poi.jar jdk 1.6 tomcat 7.0 eclipse 4.4.0 本 Demo 是在 SpringMVC框架中实现. 页面 export.jsp 很简单,就只有一个超链接. <%@ page language="java" contentType="text/html; charset=

  • SpringMVC框架整合Junit进行单元测试(案例详解)

    本文主要介绍在SpringMVC框架整合Junit框架进行单元测试.闲话少述,让我们直入主题. 系统环境 软件 版本 spring-webmvc 4.3.6.RELEASE spring-test 4.3.6.RELEASE junit 4.12 引入依赖 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</ver

  • SpringMvc框架的简介与执行流程详解

    目录 一.SpringMvc框架简介 1.Mvc设计理念 2.SpringMvc简介 二.SpringMvc执行流程 1.流程图解 2.步骤描述 3.核心组件 三.整合Spring框架配置 1.spring-mvc配置 2.Web.xml配置 3.测试接口 4.常用注解说明 四.常见参数映射 1.普通映射 2.指定参数名 3.数组参数 4.Map参数 5.包装参数 6.Rest风格参数 五.源代码地址 一.SpringMvc框架简介 1.Mvc设计理念 M:代表模型Model 模型就是数据,应用

  • SpringMVC框架如何与Junit整合看这个就够了

    目录 系统环境 引入依赖 编写单元测试基类 MockMvcRequestBuilders get请求测试 post请求测试 文件上传测试 返回结果是视图请求的单元测试 直接测试一个service的方法 总结 系统环境 软件 版本 spring-webmvc 4.3.6.RELEASE spring-test 4.3.6.RELEASE junit 4.12 引入依赖 <dependency> <groupId>junit</groupId> <artifactId

  • SpringMVC框架REST架构体系原理分析

    目录 资源(Resource) 表现层(Representation) 状态转换(State Transfer) 如何使用 1.在Handler写出增删改查的方法 2.Repository 资源(Resource) 资源是网络上的⼀个实体,或者说网络中存在的⼀个具体信息,⼀段⽂本.⼀张图片.⼀⾸歌曲.⼀段视频等等,总之就是⼀个具体的存在.可以用⼀个 URI(统⼀资源定位符)指向它,每个资源都有对应的⼀个 特定的 URI,要获取该资源时,只需要访问对应的 URI 即可. 表现层(Represent

随机推荐