溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用nodejs+koa2 如何模仿springMVC框架

發(fā)布時間:2020-10-26 16:33:45 來源:億速云 閱讀:180 作者:Leah 欄目:開發(fā)技術(shù)

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)使用nodejs+koa2 如何模仿springMVC框架,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1、在硬盤上新增一個文件夾,打開VSC,點擊‘添加工作區(qū)文件夾',如果沒有歡迎‘使用頁面',點擊--文件--新建窗口,效果如下圖:

使用nodejs+koa2 如何模仿springMVC框架

使用nodejs+koa2 如何模仿springMVC框架

2、添加vsc調(diào)試。Shift+ctrl+p,輸入框內(nèi)輸入:launch.json

使用nodejs+koa2 如何模仿springMVC框架

選擇剛剛的文件夾

使用nodejs+koa2 如何模仿springMVC框架

使用nodejs+koa2 如何模仿springMVC框架

3、目錄結(jié)構(gòu)

使用nodejs+koa2 如何模仿springMVC框架

從低到高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"
 }
}

參數(shù)介紹:name項目名稱、version版本號、description項目描述、main項目啟動文件、scripts啟動快捷設(shè)置,author作者,dependencies第3方中間件名稱及版本。

3-2、app.js

//啟動服務(wù)
require('./config/init').startServer();

啟動相關(guān)配置,封裝到config/init.js中,啟動文件直接引用即可。

3-3、views存放html頁面

3-4、static存放靜態(tài)文件,css,js,font等

3-5、src存放業(yè)務(wù)控制,類似于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參數(shù)`);
   }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="系統(tǒng)內(nèi)部錯誤!";
       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();
 };
}

啟動構(gòu)建

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項目參數(shù)配置。

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相關(guān)方法封裝。

const jwt = require("jsonwebtoken");
const config = require('./config');
/**
 * 創(chuàng)建token的方法
 */
let createToken = (data)=>{
 let obj = {};
 //存入token的數(shù)據(jù)
 obj.data = data || {};
 //token的創(chuàng)建時間
 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、項目結(jié)構(gòu)構(gòu)建結(jié)束,接著引入所有依賴包,在終端中執(zhí)行‘npm install' ,會下載package.json中dependencies所有包,以及這些包所依賴的包。

使用nodejs+koa2 如何模仿springMVC框架

執(zhí)行后項目結(jié)構(gòu)會增加兩個文件

使用nodejs+koa2 如何模仿springMVC框架

5、編寫測試用例,在src下新建hello.js。

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

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


var fn_index = async (ctx, next) => {
 ctx.response.body = `<h2>Index</h2>
  <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 = `<h2>Welcome, ${name}!</h2><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、啟動項目

使用nodejs+koa2 如何模仿springMVC框架

啟動成功

使用nodejs+koa2 如何模仿springMVC框架

測試訪問:http://127.0.0.1:3000/koa/login

使用nodejs+koa2 如何模仿springMVC框架

輸入值獲取token

使用nodejs+koa2 如何模仿springMVC框架

使用nodejs+koa2 如何模仿springMVC框架

先不用帶token進行訪問

使用nodejs+koa2 如何模仿springMVC框架

攔截成功

帶上token 進行訪問

使用nodejs+koa2 如何模仿springMVC框架

測試成功!

上述就是小編為大家分享的使用nodejs+koa2 如何模仿springMVC框架了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI