本教程将教导大家如何用Node.js语言搭建一个Web端文件词频统计动态网页。
教程需求
在网页中指定词频文件路径,利用网页点击提交,提交后程序自动运行WordCount的MapReduce程序的JAR包,对HDFS中的文件进行词频统计,并把统计结果显示在网页上。
开发环境
NVM Node版本管理工具
Node.js --LTS
Hadoop 2.7.4
Visual Studio Code 文本编辑工具
安装nvm
打开终端,输入如下命令
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
然后用vim打开 ~/.bashrc
vim ~/.bashrc
进入编辑模式,添加NVM_DIR环境变量
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This
:wq退出vim的编辑模式,在终端中输入如下命令
source ~/.bashrc
更多有关NVM的教程,请点击访问GitHub NVM官方地址
利用nvm安装Node长期支持版本
nvm install --lts
安装完成后,在终端输入如下命令,即可看到node安装的版本
node -v
运行Hadoop伪分布式
如果已经安装好Hadoop的伪分布式,请跳过本步骤
如果还未安装好Hadoop的伪分布式,请点击Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04,按照此教程进行安装。
运行Hadoop伪分布式命令后,我们还需要使用之前教程中使用的WordCount.jar包。
如果没有这个Jar包,请参考教程使用命令行编译打包运行自己的MapReduce程序 Hadoop2.6.0,自行导出Jar包。
本教程中,我导出的Jar包位于路径是'~/WordCount.jar'
终端中执行如下命令:
cd /usr/local/hadoop
sbin/start-dfs.sh
项目开发
终端输入如下命令
# 创建项目文件夹
mkdir myapp
# 初始化项目
cd myapp
npm init
初始化项目后,终端会让你输入项目的相关信息,并自动把这些信息记录在package.json中。
如果想快捷进行开发,不想手动输入项目信息,只需要一路按“Enter”键即可,接受默认自动配置。
安装Express开发框架
npm install express --save
通过npm --save安装的模块都会放在当前项目文件夹下的node_modules文件夹下,并更新到package.json文件中。node中引用该模块的时候,会自动从node_modules文件夹下寻找模块。
Hello world实例
在myapp项目目录中,创建一个名为index.js的文件,这个文件将是整个应用的入口。将如下代码复制进去
const express = require('express');
const app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
const server = app.listen(3000, function () {
const host = server.address().address;
const port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
上面的代码启动一个服务并监听从 3000 端口进入的所有连接请求。他将对所有 (/) URL 或 路由 返回 “Hello World!” 字符串。对于其他所有路径全部返回 404 Not Found。
然后在终端中输入如下命令,启动该应用
node index.js
OK,一个最原始的网站就实现了,在浏览器中输入http://locahost:3000 就可以查看结果.
添加模板引擎
上面的Hello world实例只是教大家实现一个简单Web服务网站,没有添加任何模板引擎。这里将完善整个项目需求功能。
Jade是超高性能的node JavaScript模板引擎,有着非常强大的API和大量杰出的特性。
项目文件夹中继续添加jade模板引擎软件包,在终端中执行如下命令
npm install jade --save
安装好后,还需要在应用中设置模板文件目录、识别模板引擎。
在项目文件夹下的应用入口index.js文件下,添加如下内容:
app.set('views', './views')
app.set('view engine', 'jade')
设置好后,在项目文件夹下添加views文件夹,并在views目录下添加一个index.jade的Jade模板文件。
html
head
title!= title
body
h1!= message
如果想了解更多jade模板的语法,请参考Jade官方文档.
返回应用入口index.js文件下,修改index.js代码,如下
app.get('/', function (req, res) {
res.render('index', { title: 'WordCount测试', message: '厦门大学数据库实验室'})
})
此时在终端中重新执行如下命令:
node index.js
浏览器再次访问localhost:3000,模板文件“index.jade”就会被渲染成html.
完善模板引擎index.jade文件
修改index.jade模板文件,增加模板的form等标签。
html
head
title!= title
body
h1!= message
form(action='/', method='post')
p 请在下面输入所需要进行词频统计文件的路径
p HDFS文件路径示例:
p 本地文件路径示例:
br
input(name='path')
input(type='submit')
br
textarea(rows='40', cols='40')!=result
这里只是使用简单的页面效果,如果想增加更多的页面效果,请自行添加css、js文件。
index.js应用入口增加路由等功能
node.js要获取从前端post过去的,还需要安装body-parser,才能识别post过来的数据.
在终端中输入执行如下命令
npm install body-parser --save
然后利用node.js中child_process模块执行外部命令,并获取外部命令的输出结果.
完整的index.js代码如下:
const express = require('express')
const bodyParser = require('body-parser')
const exec = require('child_process').exec
const app = express();
// 设置模板引擎
app.set('views','./views')
app.set('view engine', 'jade')
// 添加body-parser解析post过来的数据
app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json())
app.get('/', function (req, res) {
res.render('index', {title: 'WordCount测试', message: '厦门大学数据库实验室!'})
})
app.post('/',function(req, res){
const path = req.body.path.trim()
const jarStr = '/usr/local/hadoop/bin/hadoop jar ~/WordCount.jar ' + path +' /output'
const rmrStr = '/usr/local/hadoop/bin/hadoop fs -rmr /output'
const catStr = '/usr/local/hadoop/bin/hadoop fs -cat /output/part-r-00000'
exec(rmrStr,function(err, stdout, stderr){
exec(jarStr, function(err, stdout, stderr){
// 判断路径是否存在,如果路径不存在,则显示错误信息
if(stderr){
res.render('index', {title: 'WordCount测试', message: '厦门大学数据库实验室!', result: stderr})
}
//执行成功后,显示统计结果。
exec(catStr,function(err, stdout, stderr){
res.render('index', {title: 'WordCount测试', message: '厦门大学数据库实验室!', result: stdout})
})
})
})
})
const server = app.listen(3000, function () {
const host = server.address().address;
const port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
到目前为止,一个简易的Web端文件词频统计动态网页已经搭建完成。