Node.js:集成QQ信任登录
1、申请AppId、AppKey和验证字符串
http://connect.qq.com/manage/login
网站首页头文件添加验证字符串,如:
<meta property=”qc:admins” content=”765754250763563070636” />
填写回调地址:
必须是公网地址,可以填写多个,注意 /xxx 和 http://wizzer.cn/xxx 是两个地址,两个都需要配置。
2、开发完成
登录页面:
<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/openapi/qc_loader.js" data-appid="" data-redirecturi="/public/shop/pc/account/oauthQq" charset="utf-8" >
QC.Login({
btnId:"qqLoginBtn", //插入按钮的节点id
scope: "get_user_info"
},function(oInfo, oOpts){
//登陆成功执行
var nickname=QC.String.escHTML(oInfo.nickname);//获取QQ会员名
var info={
nickname:nickname,
gender:oInfo.gender,
headimgurl:oInfo.figureurl_qq_1 //头像40X40
};//封装对象
if(QC.Login.check()){
QC.Login.getMe(function(openId, accessToken){
info.openid=openId;//传递openid及昵称头像等,业务逻辑自动注册会员或登录
$.post(
"/public/shop/pc/account/oauthQqStatus",
info,
function(result){
console.log(result);
if(result.code==0){
window.location.href=$("#r").val()||'/member';//登录成功跳转
}else{
alert('登录失败');
}
},'json'
);
});
}
});
回调页面:
退出登录:
<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/openapi/qc_loader.js" data-appid="" data-redirecturi="http:///public/shop/pc/account/oauthQq" charset="utf-8" >
QC.Login.signOut();
if(QC.Login.check()==false){
window.location.href='/public/shop/pc/account/logout';//先QQ登出,再清除session
}else{
window.location.reload();
}
window.location.href='/public/shop/pc/account/logout';
3、申请审核
审核条件:登录页面有QQ登录图标、使用申请的QQ或测试QQ号,测试可以正常登录后提交申请,否则肯定是不通过的。
Node.js 商城系统开发进展
Nginx+Tomcat负载均衡、绑定多域名、设置开机启动的安装步骤
1、JDK安装 /data1/soft/java/ >>chmod 777 jdk-6u45-linux-x64-rpm.bin >>jdk-6u45-linux-x64-rpm.bin >>gedit /etc/profile JAVA_HOME=/data1/soft/java/jdk1.6.0_45
CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME export CLASSPATH export PATH >>source /etc/profile
2、TOMCAT安装 将原windows系统中的tomcat主要文件拷贝到linux(conf、lib、bin),并新建空文件夹(logs、temp、work) /data1/soft/tomcat1 多网站的那个tomcat /data1/soft/tomcat2 少网站的那个tomcat 分别修改两个tomcat下的server.xml文件,将项目路径分别替换为 /data1/www/websties1 和 /data1/www/websties2 >>/data1/soft/tomcat/bin/startup.sh //启动tomcat >>/data1/soft/tomcat/bin/shutdown.sh //停止tomcat
开机启动: http://jingyan.baidu.com/article/6525d4b1382f0aac7d2e9421.html 【tomcat1、tomcat2分别设置为启动项】 除了百度经验之外,要在catalina.sh 里加上下面三行,否则在自启动的时候找不到jdk export JAVA_HOME=/data1/soft/java/jdk1.6.0_45 export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH
3、Nginx安装 >>rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm >>yum -y install nginx 通过命令安装后 配置文件:/etc/nginx/nginx.conf 域名配置:/etc/nginx/conf.d/ 一个域名一个配置文件,不要的域名可以备份后删除
server { listen 80; server_name test.wizzer.cn; location / { proxy_pass http://test.wizzer.cn:8101; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
日志文件路径:/var/logs/nginx 服务启动或通知 >>service nginx stop >>service nginx start 设置为随机启动 >>chkconfig nginx on
4、Nginx代理权限设置 若通过域名+端口号可访问,但80端口显示 502 Bad Gateway ,日志/var/logs/nginx/error.log报 2015/12/19 18:02:03 [crit] 9978#0: *8 connect() to 61.132.139.155:8101 failed (13: Permission denied) while connecting to upstream, client: 124.73.13.21, server: test.wizzer.cn, request: “GET / HTTP/1.1”, upstream: “http://61.132.139.155:8101/“, host: “test.wizzer.cn” 则需要设置selinux权限(宽容模式): >>setenforce 0 >>setsebool -P httpd_can_network_connect 1
5、防火墙配置 >>vi /etc/sysconfig/iptables #########################################################
Firewall configuration written by system-config-firewall
Manual customization of this file is not recommended.
- *filter
- INPUT ACCEPT [0:0]
- FORWARD ACCEPT [0:0]
- OUTPUT ACCEPT [0:0] -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 21 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT -A INPUT -j REJECT –reject-with icmp-host-prohibited -A FORWARD -j REJECT –reject-with icmp-host-prohibited COMMIT #########################################################
>>/etc/init.d/iptables restart #重启防火墙使配置生效,或者命令 service iptables restart
LNMP:Nginx+PHP Ci框架配置注意事项
CodeIgniter
php.ini 修改:
cgi.fix_pathinfo=1
nginx/vhost/ 域名配置:
server { listen 80; server_name www.wizzer.cn wizzer.cn; root “/data/www/www.wizzer.cn”; location / { index index.html index.htm index.php; if (!-e $request_filename) { rewrite ^/(.)$ /index.php?$1 last; break; } } location ~ .php(.)$ { fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; fastcgi_split_path_info ^(.+.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include fastcgi_params; } }
Node.js:集成百度编辑器的上传功能
Ueditor1.4.3.1版本,仅贴了图片上传代码,其他自己加。。。
/**
* Created by root on 11/16/15.
*/
var fs = require('fs-extra');
var moment = require("moment");
module.exports = {
index: function (req, res) {
if (req.session.auth && !req.session.user.disabled) {
var action = req.query.action;
//加载配置文件
fs.readFile(sails.config.appPath + '/assets/plugins/ueditor/node/config.json', 'utf8', function (err, config_txt) {
var config = JSON.parse(config_txt);
switch (action) {
case 'config':
return res.send(config_txt);
break;
case 'uploadimage':
req.file('Filedata').upload({
maxBytes: config.imageMaxSize
}, function (err, uploadedFiles) {
if (err)return res.json({state: sails.__('file.upload.err')});
var filename = uploadedFiles[0].filename;
var type = uploadedFiles[0].type;
var fd = uploadedFiles[0].fd;
var size = uploadedFiles[0].size;
console.log('uploadimage:::' + JSON.stringify(uploadedFiles));
if(config.imageAllowFiles.indexOf(fd.substring(fd.lastIndexOf('.')))<0)
return res.json({state: sails.__('file.upload.err')});
var file = fd.substring(fd.lastIndexOf('/'));
var newPath = sails.config.system.AppBase + sails.config.system.UploadPath + "/image/" + moment().format("YYYYMMDD") + file;
fs.copy(fd, sails.config.appPath + newPath, function (err) {
if (err)return res.json({state: sails.__('file.upload.err')});
return res.json({state: 'SUCCESS', url: newPath, title: filename, original: filename, type: type, size: size});
})
});
break;
}
});
} else {
return res.json({state: sails.__('private.forbidden'), url: '', title: '', original: '', type: '', size: 0});
}
}
};
Node.js:微信消息回复、推送的实现
适应场景:Sails框架、微信公众号数据配置在数据库中,支持多个公众号。 1、Model定义(Waterline) 文件路径:/api/models/wx/Wx_config.js
/**
* Created by root on 10/25/15.
*/
var moment = require('moment');
module.exports = {
schema: true,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
id: {
type: 'integer',
autoIncrement: true,
primaryKey: true
},
appname: {
type: 'string',
required: true
},
ghid: {//原始ID
type: 'string',
unique: true,
required: true
},
appid: {
type: 'string',
unique: true,
required: true
},
appsecret: {
type: 'string',
unique: true,
required: true
},
encodingAESKey:{
type: 'string',
unique: true,
required: true
},
token: {
type: 'string',
unique: true,
required: true
},
access_token: {
type: 'string'
},
expire_time: {
type:'integer',
defaultsTo:function(){
return 0;
}
},
createdBy:{
type: 'integer'
},
createdAt:{
type:'integer',
defaultsTo:function(){
return moment().format('X');
}
}
}
};
2、Sails默认不支持微信xml post,改造之 文件路径:/config/http.js
rawParser: function(req, res, next) {
switch(req.headers['content-type']) {
case 'text/xml':
require('body-parser').raw({ type: 'text/xml' })(req, res, next);
break;
default :
next();
}
},
order: [
'startRequestTimer',
'cookieParser',
'session',
'myRequestLogger',
'rawParser',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'$custom',
'router',
'www',
'favicon',
'404',
'500'
],
3、控制类 文件路径:/api/controllers/open/WeixinController.js 微信公众号后台配置路径:http://127.0.0.1/open/weixin/api?wxid=1
/**
* Created by root on 10/25/15.
*/
module.exports = {
api: function (req, res) {
var id = req.query.wxid;
Wx_config.findOne(id).exec(function (err, conf) {
if (err)return res.send(200, 'fail');
if (req.body) {
WeixinService.loop(req, function (data) {
if (data.type = 'text') {//用户发送纯文本
var msg = {toUserName: data.openid, fromUserName: conf.ghid, content: 'Node.js Test...'};
WeixinService.sendTextMsg(res, msg);//向用户回复消息
}
});
}
//签名
if (WeixinService.checkSignature(req, conf.token)) {
res.send(200, req.query.echostr);
} else {
res.send(200, 'fail');
}
});
}
};
4、微信服务工具类 文件路径:/api/services/WeixinService.js
/**
* Created by root on 10/26/15.
*/
var sha1 = require('sha1'), xml2js = require('xml2js');
module.exports = {
/**
* 签名验证
* @param req
* @param token
* @returns {boolean}
*/
checkSignature: function (req, token) {
var signature = req.query.signature,
timestamp = req.query.timestamp,
nonce = req.query.nonce,
echostr = req.query.echostr;
// 按照字典排序
var array = [token, timestamp, nonce];
array.sort();
// 连接
var str = sha1(array.join(""));
// 对比签名
return str == signature;
},
/**
* 监听用户消息
* @param req
* @param callback
*/
loop: function (req, callback) {
var body = req.body.toString('utf-8');
var data = {};
xml2js.parseString(body, function (err, json) {
if (err) {
} else {
console.log('json::' + JSON.stringify(json));
data.type = json.xml.MsgType;
data.openid = json.xml.FromUserName;
if (data.type == 'text') {
data.txt = json.xml.Content;
} else if (data.type == 'image') {
data.pic = json.xml.PicUrl;
}
return callback(data);
}
});
},
/**
* 发送文本消息
* @param res
* @param msg
*/
sendTextMsg: function (res, msg) {
var time = Math.round(new Date().getTime() / 1000);
var funcFlag = msg.funcFlag ? msg.funcFlag : 0;
var output = "" +
"" +
"" +
"" +
"" + time + "" +
"" +
"" +
"" + funcFlag + "" +
"";
res.type('xml');
res.send(output);
},
/**
* 发送图文消息
* @param res
* @param msg
*/
sendNewsMsg: function (res, msg) {
var time = Math.round(new Date().getTime() / 1000);
var articlesStr = "";
for (var i = 0; i < msg.articles.length; i++) {
articlesStr += "" +
" " +
"" +
"" +
"" +
"";
}
var funcFlag = msg.funcFlag ? msg.funcFlag : 0;
var output = "" +
"" +
"" +
"" +
"" + time + "" +
"" +
"" + msg.articles.length + "" +
"" + articlesStr + "" +
"" + funcFlag + "" +
"";
res.type('xml');
res.send(output);
}
};
Nodejs版本:0.12.7 Sails版本:0.11.0 require相关组件,记得安装。 参考项目1:https://github.com/node-webot/wechat-api 参考项目2:https://github.com/JeremyWei/weixin_api
jquery.datatables 使用方法:Ajax分页、字段排序、传递参数等

Html:
姓名状态是否在线操作
用户名
datatables初始化:
var datatable;
function initDatatable() {
datatable = $('.datatable').DataTable({
"processing": false,
"serverSide": true,
"select": true,
"ordering": true,
"language": {
"url": "/plugins/datatables/cn.json"
},
"preDrawCallback": function () {
sublime.closeLoadingbar($(".main-content"));
sublime.showLoadingbar($(".main-content"));
},
"drawCallback": function () {
sublime.closeLoadingbar($(".main-content"));
},
"ajax": {
"url": "/private/sys/user/data",
"type": "post",
"data": function (d) {
d.unitid = $('#unitid').val();
d.loginname=$('#loginname').val();
d.nickname=$('#nickname').val();
}
},
"order":[[0,"desc"]],
"columns": [
{"data": "loginname", "bSortable": true},
{"data": "nickname", "bSortable": true},
{"data": "disabled", "bSortable": true},
{"data": "online", "bSortable": true}
],
"columnDefs": [
{
"render": function (data, type, row) {
return 'html.....';
},
"targets": 4
},
{
"render": function (data, type, row) {
if (data) {
return '';
} else {
return '';
}
},
"targets": 3
},
{
"render": function (data, type, row) {
if (!data) {
return '';
} else {
return '';
}
},
"targets": 2
}
]
});
datatable.on('click', 'tr', function () {
$(this).toggleClass('selected');
});
$("#searchBtn").on('click',function(){
datatable.ajax.reload(null, false);
});
}
重新加载数据:
datatable.ajax.reload(null, false);//当前页 datatable.ajax.reload();//回到第一页
排序:通过后台参数 order数组得到dir:asc/desc,通过order的column下标,获取columns数组中的data字段名,两者结合写排序条件 后台把所有参数打印出来,你就知道代码应该怎么写了……over
响应的数据格式:
{
"draw": draw,
"recordsTotal": pageSize,
"recordsFiltered": count,
"data": list
}
Nodejs 后端完整代码:
data: function (req, res) {
var pageSize = parseInt(req.body.length);
var start = parseInt(req.body.start);
var page = start / pageSize + 1;
var draw = parseInt(req.body.draw);
var unitid = req.body.unitid || 1;
var loginname = req.body.loginname || '';
var nickname = req.body.nickname || '';
var order = req.body.order || [];
var columns = req.body.columns || [];
var sort = {};
var where = {unitid: unitid};
if (loginname) {
where.loginname = {'like':'%'+loginname+'%'};
}
if (nickname) {
where.nickname = {'like':'%'+nickname+'%'};
}
if (order.length > 0) {
sort[columns[order[0].column].data] = order[0].dir;
}
Sys_user.count(where).exec(function (err, count) {
if (!err && count > 0) {
Sys_user.find(where)
.sort(sort)
.paginate({page: page, limit: pageSize})
.exec(function (err, list) {
return res.json({
"draw": draw,
"recordsTotal": pageSize,
"recordsFiltered": count,
"data": list
});
});
} else {
return res.json({
"draw": draw,
"recordsTotal": pageSize,
"recordsFiltered": 0,
"data": []
});
}
});
},
CentOS:6.5防火墙设置开放端口
1) 打开端口 vi /etc/sysconfig/iptables
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT 注意:新开放的端口一定要在端口22后面
重启防火墙使配置生效 /etc/init.d/iptables restart
查看开放端口 /etc/init.d/iptables status
1) 永久性生效,重启后不会复原
开启: chkconfig iptables on
关闭: chkconfig iptables off
2) 即时生效,重启后复原
开启: service iptables start
关闭: service iptables stop
Sails:Waterline多对多查询
Sys_user.js
module.exports = {
schema: true,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
id: {
type: 'integer',
autoIncrement: true,
primaryKey: true
},
roles: {
collection: 'Sys_role',
via: 'users'
}
}
};
Sys_role.js
users: {
collection: 'Sys_user',
via: 'roles'
//dominant: true
},
使用populate查询
Sys_role.findOne(1).populate('users').populate('menus').exec(function(err, role) {
console.log(':::'+JSON.stringify(role.users));
console.log(':::'+JSON.stringify(role.menus));
});
Node:加盐salt密码验证
npm install bcrypt –save
var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync(‘pass’, salt); console.log(‘加密::’+hash); console.log(‘解密::’+bcrypt.compareSync(‘pass’,hash));
Node:搭建sails.js开发环境
友情提示:do not 在windows下开发node.js应用,否则你会浪费很多时间并且会pia撞墙的…… 1.CentOS6.5 安装 nodejs 并配置到环境
>>gedit /etc/profile export NODE_HOME=/soft/node-v0.12.7-linux-x64 export PATH=$NODE_HOME/bin:$PATH >>source /etc/profile >>node -v
2.npm 设置为国内源
>>npm config set registry https://registry.npm.taobao.org
3.安装必备模块 node-gyp (CentOS6.5 自带Python2.6.6)
>>npm install node-gyp -g
4.安装WebStorm 并安装JDK7
>>rpm -ivh jdk-7u79-linux-x64.rpm >>gedit /etc/profile JAVA_HOME=/usr/java/jdk1.7.0_79 CLASSPATH=.:$JAVA_HOME/lib.tools.jar PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH >>source /etc/profile
5.安装Git 并生成ssh密钥,github帐号设置中添加密钥
>>yum install git >>cd ~/.ssh >>ssh-keygen -t rsa -C “wizzer@qq.com” >>cat ~/.ssh/id_rsa.pub >>git clone git@github.com:Wizzercn/nodeshop.git
>>git pull >>git commit -am ‘note’ >>git push
6.验证码组件ccap,需安装python2.7
http://blog.csdn.net/tiantiandjava/article/details/17242345 >>npm install ccap –save
Nutz:集成 CXF Webservice [通过cxf-servlet.xml配置文件]
pom.xml
org.apache.cxf
cxf-api
2.7.15
org.apache.cxf
cxf-rt-frontend-jaxws
2.7.15
org.apache.cxf
cxf-rt-bindings-soap
2.7.15
org.apache.cxf
cxf-rt-transports-http
2.7.15
org.apache.cxf
cxf-rt-ws-security
2.7.15
org.springframework
spring-web
4.1.5.RELEASE
web.xml
CXFServlet
org.apache.cxf.transport.servlet.CXFServlet
1
CXFServlet
/webservice/*
cxf-servlet.xml
接口类 WorkflowService.java
package com.auto.webservice.server;
import org.nutz.json.Json;
import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by wizzer on 15-4-13.
*/
@WebService(targetNamespace = "http://server.webservice.auto.com/", name = "workflowServicePortType")
public interface WorkflowService {
@WebResult(name = "return")
@Action(input = "urn:start", output = "urn:startResponse")
@RequestWrapper(localName = "start")
@WebMethod(action = "urn:start")
@ResponseWrapper(localName = "startResponse")
String start(@WebParam(name = "flowKey") String flowKey, @WebParam(name = "userId") String userId);//启动流程
}
实现类
WorkflowServiceImpl.java
package com.auto.webservice.server;
import org.activiti.engine.*;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.StartFormData;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by wizzer on 15-4-13.
*/
@IocBean(name = "workflowService")
@WebService
public class WorkflowServiceImpl implements WorkflowService {
private final Log log = Logs.get();
FormService formService=Mvcs.ctx().getDefaultIoc().get(FormService.class);
IdentityService identityService=Mvcs.ctx().getDefaultIoc().get(IdentityService.class);
RuntimeService runtimeService=Mvcs.ctx().getDefaultIoc().get(RuntimeService.class);
TaskService taskService=Mvcs.ctx().getDefaultIoc().get(TaskService.class);
RepositoryService repositoryService=Mvcs.ctx().getDefaultIoc().get(RepositoryService.class);
/**
* 启动一个流程
*
* @param flowKey 流程模型key
* @param userId 用户ID
* @return
*/
public String start(String flowKey, String userId) {
Map map = new HashMap();
try {
if (!Strings.isEmpty(userId)) {
identityService.setAuthenticatedUserId(userId);
}
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(flowKey);
map.put("errcode", 0);
map.put("errmsg", "");
map.put("processInstanceId", processInstance.getId());
} catch (Exception e) {
log.error("WebServcice启动流程出错", e);
map.put("errcode", 1);
map.put("errmsg", e.getMessage());
} finally {
identityService.setAuthenticatedUserId(null);
}
return Json.toJson(map, JsonFormat.compact());
}
}
/**
* IP地址拦截器
*
* @author Sunshine
*/
public class IpAddressInInterceptor extends AbstractPhaseInterceptor {
private final Log log = Logs.get();
public IpAddressInInterceptor() {
super(Phase.RECEIVE);
}
public void handleMessage(Message message) throws Fault {
HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
//获取所有的白名单访问主机
UserInfoServiceImpl userInfoService = Mvcs.ctx().getDefaultIoc().get(UserInfoServiceImpl.class);
List hostList = userInfoService.queryHostListByType("w");
// 取客户端IP地址
String ipAddress = request.getRemoteAddr();
// 如果允许访问的集合非空,继续处理,否则认为全部IP地址均合法
if (!hostList.isEmpty()) {
boolean contains = false;
for (ListInfo hostInfo : hostList) {
log.debug("hostInfo:" + hostInfo.getIpaddress() + "|ipAddress:" + ipAddress);
if (hostInfo.getIpaddress().equals(ipAddress)) {
contains = true;
break;
}
}
if (!contains) {
throw new Fault(new IllegalAccessException("IP address " + ipAddress + " is not allowed"));
}
}
}
}
Centos:安装mysql
yum update
yum search mysql
yum list mysql
yum list mysql-server
yum install mysql
yum install mysql-server
运行命令chkconfig –levels 235 mysqld on使MySQL服务可以自动启动,并使用命令/etc/init.d/mysqld start立刻启动MySQL服务
设置MySQL的root密码,运行命令/usr/bin/mysqladmin -u root password ‘new-password’,其中’new-password’是新设的密码,如123456
WSO2:配置webservice代理 地址不对的问题
Activiti:获取节点走向
@At
public String test5(@Param("taskId") String taskId) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null)
return "null";
ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());
List activitiList = def.getActivities();
System.out.println("getTaskDefinitionKey:::" + task.getTaskDefinitionKey());
NutMap map = new NutMap();
int type = 0;
getTaskActivitys(task.getTaskDefinitionKey(), activitiList, type, map);
return Json.toJson(map);
}
public static List getTaskActivitys(String activityId, List activityList, int type, NutMap map) {
List activitiyIds = new ArrayList();
for (ActivityImpl activityImpl : activityList) {
String id = activityImpl.getId();
if (activityId.equals(id)) {
List outgoingTransitions = activityImpl.getOutgoingTransitions();//获取某节点所有线路
List list = new ArrayList();
for (PvmTransition tr : outgoingTransitions) {
NutMap map1 = new NutMap();
PvmActivity ac = tr.getDestination();//获取线路的终点节点
if (ac.getProperty("type").equals("userTask")) {
map.setv("type", type++);
map1.setv("id", ac.getId());
map1.setv("name", ac.getProperty("name"));
String conditionText=Strings.sNull(tr.getProperty("conditionText"));
if(!Strings.isEmpty(conditionText)){
map1.setv("conditionText",conditionText );
}
list.add(map1);
} else if (ac.getProperty("type").equals("exclusiveGateway")) {
getTaskActivitys(ac.getId(), activityList, type, map);
} else {
map.setv("type", type++);
break;
}
}
if (list.size() > 0)
map.addv("list", list);
break;
}
}
return activitiyIds;
}
Nutz:集成CXF webservice
pom.xml
org.apache.cxf
cxf-api
2.7.15
org.apache.cxf
cxf-rt-frontend-jaxws
2.7.15
org.apache.cxf
cxf-rt-bindings-soap
2.7.15
org.apache.cxf
cxf-rt-transports-http
2.7.15
org.apache.cxf
cxf-rt-ws-security
2.7.15
web.xml
CXFServlet
com.auto.webservice.servlet.CXFServlet
1
CXFServlet
/webservice/*
CXFServlet.java:
package com.auto.webservice.servlet;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
import org.nutz.ioc.Ioc;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import javax.jws.WebService;
import javax.servlet.ServletConfig;
import javax.xml.namespace.QName;
/**
* Created by wizzer on 15-4-10.
*/
@SuppressWarnings("serial")
public class CXFServlet extends CXFNonSpringServlet {
private final Log log = Logs.get();
@Override
protected void loadBus(ServletConfig sc) {
super.loadBus(sc);
//全局配置
Bus bus = getBus();
//添加白名单过滤器
bus.getInInterceptors().add(new IpAddressInInterceptor());
//使用全局配置
BusFactory.setDefaultBus(bus);
Ioc ioc = Mvcs.ctx().getDefaultIoc();
for (String name : ioc.getNames()) {
try {
Object obj = ioc.get(null, name);
if (!obj.getClass().getPackage().getName().equals("com.auto.webservice.server")) {
continue;
}
if (obj.getClass().getAnnotation(WebService.class) == null)
continue;
Class face = Class.forName(obj.getClass().getPackage().getName() + "." + Strings.upperFirst(name));
ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
// 设置服务接口类
serverFactoryBean.setServiceClass(face);
// 服务请求路径
serverFactoryBean.setAddress("/" + name.substring(0, name.indexOf("Service")));
// 设置服务实现类
serverFactoryBean.setServiceBean(obj);
serverFactoryBean.setBindingId("http://schemas.xmlsoap.org/wsdl/soap12/");
serverFactoryBean.create();
} catch (Throwable e) {
}
}
}
}
接口类
WorkflowService.java
package com.auto.webservice.server;
import org.nutz.json.Json;
import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by wizzer on 15-4-13.
*/
@WebService
public interface WorkflowService {
String start(String flowKey, String userId);//启动流程
}
实现类
WorkflowServiceImpl.java
package com.auto.webservice.server;
import org.activiti.engine.*;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.StartFormData;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by wizzer on 15-4-13.
*/
@IocBean(name = "workflowService")
@WebService
public class WorkflowServiceImpl implements WorkflowService {
private final Log log = Logs.get();
@Inject
Dao dao;
@Inject
FormService formService;
@Inject
IdentityService identityService;
@Inject
RepositoryService repositoryService;
@Inject
RuntimeService runtimeService;
@Inject
TaskService taskService;
/**
* 启动一个流程
*
* @param flowKey 流程模型key
* @param userId 用户ID
* @return
*/
public String start(String flowKey, String userId) {
Map map = new HashMap();
try {
if (!Strings.isEmpty(userId)) {
identityService.setAuthenticatedUserId(userId);
}
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(flowKey);
map.put("errcode", 0);
map.put("errmsg", "");
map.put("processInstanceId", processInstance.getId());
} catch (Exception e) {
log.error("WebServcice启动流程出错", e);
map.put("errcode", 1);
map.put("errmsg", e.getMessage());
} finally {
identityService.setAuthenticatedUserId(null);
}
return Json.toJson(map, JsonFormat.compact());
}
}
Nutz 集成Activiti5.17.0 [03]扩展用户、组使用自己的数据表
首先值得一提的是,taskService.createTaskQuery().taskCandidateOrAssigned(userId) 方法有bug,不会调用重写的工厂类,请使用taskService.createTaskQuery().taskCandidateUser(userId)方法。
CustomGroupEntityManager
/**
* 分组工厂类
* Created by wizzer on 15-4-27.
*/
@IocBean
public class CustomGroupEntityManager extends GroupEntityManager {
Dao dao= Mvcs.getIoc().get(Dao.class);
private final Log log = Logs.get();
@Override
public List findGroupsByUser(String userId) {
Sql sql = Sqls.create("SELECT a.* FROM sys_role a,sys_user_role b WHERE a.id=b.roleid AND b.userid=@c");
sql.params().set("c", userId);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
List
CustomGroupEntityManagerFactory
/**
* 分组接口类
* Created by wizzer on 15-4-27.
*/
@IocBean
public class CustomGroupEntityManagerFactory implements SessionFactory {
private GroupEntityManager groupEntityManager;
public void setGroupEntityManager(GroupEntityManager groupEntityManager) {
this.groupEntityManager = groupEntityManager;
}
@Override
public Class getSessionType() {
return GroupIdentityManager.class;
}
@Override
public Session openSession() {
return groupEntityManager;
}
}
CustomUserEntityManager
/**
* 用户工厂类
* Created by wizzer on 15-4-24.
*/
@IocBean
public class CustomUserEntityManager extends UserEntityManager {
Dao dao= Mvcs.getIoc().get(Dao.class);
private final Log log = Logs.get();
@Override
public User findUserById(String userId) {
log.info("findUserById:::::::::::::::::::::::::::::::"+userId);
UserEntity userEntity = new UserEntity();
Sys_user sysUser = dao.fetch(Sys_user.class, Cnd.where("uid", "=", userId));
userEntity.setId(userId);
userEntity.setFirstName(sysUser.getRealname());
userEntity.setEmail(sysUser.getEmail());
userEntity.setRevision(1);
return userEntity;
}
@Override
public List findGroupsByUser(String userId) {
// TODO Auto-generated method stub
log.info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
Sql sql = Sqls.create("SELECT a.* FROM sys_role a,sys_user_role b WHERE a.id=b.roleid AND b.userid=@c");
sql.params().set("c", userId);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
List
CustomUserEntityManagerFactory
/**
* 用户接口类
* Created by wizzer on 15-4-24.
*/
@IocBean
public class CustomUserEntityManagerFactory implements SessionFactory {
private UserEntityManager userEntityManager;
public void setUserEntityManager(UserEntityManager userEntityManager) {
this.userEntityManager = userEntityManager;
}
@Override
public Class getSessionType() {
return UserIdentityManager.class;
}
@Override
public Session openSession() {
return userEntityManager;
}
}
Nutz 集成Activiti5.17.0 [01]初始化activiti
在初始化activiti时追加代码:
List list=new ArrayList();
CustomGroupEntityManagerFactory customGroupManagerFactory=new CustomGroupEntityManagerFactory();
customGroupManagerFactory.setGroupEntityManager(new CustomGroupEntityManager());
CustomUserEntityManagerFactory customUserEntityManagerFactory=new CustomUserEntityManagerFactory();
customUserEntityManagerFactory.setUserEntityManager(new CustomUserEntityManager());
list.add(customGroupManagerFactory);
list.add(customUserEntityManagerFactory);
processEngineConfiguration.setCustomSessionFactories(list);
Nutz 集成Activiti5.17.0 [02]集成流程设计器及汉化
下载 activiti-modeler 源码,里面的方法用nutz重写,然后修改editor-app里面页面和js里对应的路径。
5.17.0汉化文件下载:http://pan.baidu.com/s/1qWlzHDE
细节不多述了,自己动手吧,哇哈哈……




