网站被攻击了
来源IP :114.226.31.36,一直刷我流量,一个小时干掉8G。
还好我有短信提醒。
昨天把这个IP拉黑后,今天又换成 114.226.31.26 来刷,只好把这个网段拉黑,然后持续监测。
不知道对方什么目的,来搞我这个小网站。
来源IP :114.226.31.36,一直刷我流量,一个小时干掉8G。
还好我有短信提醒。
昨天把这个IP拉黑后,今天又换成 114.226.31.26 来刷,只好把这个网段拉黑,然后持续监测。
不知道对方什么目的,来搞我这个小网站。
使用 WPF + CefSharp 技术,C/S客户端 + B/S浏览器的组合,利用客户端实现IC卡读写器的集成开发,实现IC卡表的读写功能,利用B/S浏览器,将营收系统嵌入浏览器,实现WEB营收业务代码热更新、数据统一管理等功能。
抽象设备接入层,实现电信AEP平台、移动OneNET、厂家物联网平台等平台接入,实现 NB-IOT/MQTT/HTTP 等协议的适配和转换,将各表厂繁杂不一的数据格式转换为本平台统一数据格式,并利用规则引擎技术,实现数据的智能化处理。
系统内置预付费、后付费、表端计费等计费类型,支持“购气/退气”和“充值/退费”等业务形态,支持阶梯计价、区域计价等价格规则。
燃气报装、报修、维修、安检等业务流程标准化、制度化,通过流程配置、节点配置、权限配置等,实现业务工单的动态分配和统一管理。
采用 BudWk 国产微服务分布式架构,基于 nutzboot + dubbo + nacos + druid 技术体系,核心框架为国产开源框架 nutzboot,采用 Sa-Token权限系统及JWT。根据业务划分微服务模块,如:
采用 Vite + Vue3 + ElementPlus 常用组合,前后端分离开发模式,封装集成多语言、路由、权限控制、文件上传等功能。
BudWk(原名NutzWk)发展自2010年,2012年开始用于商业项目,至今已服务于全国各地公司大大小小数千个项目,行业涉及政务、电商、物联网等,随着个人经验积累及从事行业的不同分别发布了1.x至8.x多个版本,您可以根据项目规模选择不同版本。本项目案例众多,省厅级项目、市级平台、大数据项目、电商平台、物联网平台等等。
https://demo.budwk.com V8演示地址
https://nutzwk.wizzer.cn V5演示地址
https://budwk.com 官网及开发指南
后台JAVA代码:
package cn.wizzer.app.web.modules.controllers.front.wx; import cn.wizzer.app.web.commons.base.Globals; import cn.wizzer.app.wx.modules.services.WxAddressService; import cn.wizzer.app.wx.modules.services.WxConfigService; import org.nutz.dao.Cnd; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.Strings; import org.nutz.lang.util.NutMap; import org.nutz.log.Log; import org.nutz.log.Logs; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.weixin.at.impl.MemoryJsapiTicketStore; import org.nutz.weixin.spi.WxApi2; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * Created by wizzer on 2017/6/27. */ @IocBean @At("/public/wx/add") public class AddController { private static final Log log = Logs.get(); @Inject private WxConfigService wxConfigService; @Inject private WxAddressService wxAddressService; @At("/index/?") @Ok("beetl:/public/add/index.html") public void index(String wxid,HttpServletRequest req, HttpSession session) { WxApi2 wxApi2 = wxConfigService.getWxApi2(wxid); if (Lang.isEmpty(Globals.memoryJsapiTicketStore.get(wxid))) { Globals.memoryJsapiTicketStore.put(wxid, new MemoryJsapiTicketStore()); } MemoryJsapiTicketStore memoryJsapiTicketStore = Globals.memoryJsapiTicketStore.get(wxid); wxApi2.setJsapiTicketStore(memoryJsapiTicketStore); String url = "http://" + Globals.AppDomain + Globals.AppBase + "/public/wx/add/index/"+wxid; NutMap jsConfig = wxApi2.genJsSDKConfig(url, "getLocation"); req.setAttribute("list", wxAddressService.query(Cnd.orderBy().asc("opAt"))); req.setAttribute("jsConfig", Json.toJson(jsConfig)); } }
前台代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>电子导航</title> <link rel="stylesheet" type="text/css" href="${base!}/assets/public/wx/add/css/css.css"/> <link rel="stylesheet" href="${base!}/assets/public/wx/add/css/zepto.mdatetimer.css"> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/> <meta content="yes" name="apple-mobile-web-app-capable"/> <meta content="black" name="apple-mobile-web-app-status-bar-style"/> <meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="email=no"/> <meta name="msapplication-tap-highlight" content="no"> <meta charset="utf-8"> <script type="text/javascript"> var base = '${base!}'; </script> <script type="text/javascript" src="${base!}/assets/public/wx/add/js/zepto.js"></script> <script type="text/javascript" src="${base!}/assets/public/wx/add/js/zepto.mdatetimer.js"></script> <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> </head> <body> <header class="ds-head"> <h1>公司检索</h1> </header> <div class="time"> <div class="time-li round-a"><span>公司名称:</span><input id="name" type="text" value=""/></div> <div class="btn"><input id="btn" type="button" value="立即查询" class="round-a"/></div> <div class="time-li round-a"><span>当前位置:</span><input id="longitude" type="text" value="" readonly/><input id="latitude" type="text" value="" readonly/></div> </div> <ul class="earn"> <%for(o in list){%> <li class="earn-li"> <dl> <dt class="cf2"><span class="earn-lil">${oLP.index}、${o.name} </span></dt> <dd class="cf2"><span class="earn-lil">lng:${o.lng}, lat:${o.lat}</span></dd> <dd class="cf2"> <span><button onclick="goTo('walk','${o.name}','${o.lng}','${o.lat}');">步行</button></span> <span><button onclick="goTo('drive','${o.name}','${o.lng}','${o.lat}');">驾车</button></span> </dd> </dl> </li> <%}elsefor{%> 没有检索到结果 <%}%> </ul> <script language="JavaScript"> function goTo(type,name,lng,lat) { var longitude=$("#longitude").val(); var latitude=$("#latitude").val(); window.location.href="http://apis.map.qq.com/uri/v1/routeplan?type="+type+"&from=我的位置&fromcoord="+latitude+","+longitude+"&to="+name+"&tocoord="+lat+","+lng+"&policy=1&referer=电子导航"; //window.location.href="http://api.map.baidu.com/direction?origin=latlng:"+latitude+","+longitude+"|name:我的位置&destination=latlng:"+lat+","+lng+"|name:"+name+"&mode=driving®ion=合肥&output=html&src=电子导航"; } wx.config(${jsConfig}); wx.ready(function(){ wx.getLocation({ type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 $("#latitude").val(latitude); $("#longitude").val(longitude); } }); }); </script> </body> </html>
标致408 1.8L自豪版 2015年4月购
1、等待发动机冷却
2、刷程序(发动机和变速箱程序要同时升级)
整个过程一个半小时,师傅说刷程序是连法国服务器的,因网络原因可能会有几率刷成“砖”,成砖车就比较杯具了要放4s店一夜等修复。
因为时差的原因,法国服务器周末可能停机,所以想刷程序的车友可以在 周一下午至周五 到店,刷程序是免费的。
我是一次性成功的,比较幸运~~~
1、爽
2、非常爽
3、特点就是轻踩刹车停下来的时候,启停不会工作,车停下来后如果刹车踩到底发动机也还会停止
4、重踩刹车(刹车踩到底)停车,发动机直接停止
5、如果开空调的话,最好还是关闭启停吧,因为发动机停止后还会自动开启
堵车的时候可以轻踩刹车停车,如果等的时间比较长,这个时候把刹车踩到底发动机就停了,真正的智能启停,启停掌握在驾驶者脚上,爽啊。。
以前是上车就把启停功能关闭,现在再也不用那么麻烦了。。。
下面是车友分享的演示视频:
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}); } } };
pom.xml
<!--CXF START--> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-api</artifactId> <version>2.7.15</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>2.7.15</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-bindings-soap</artifactId> <version>2.7.15</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>2.7.15</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>2.7.15</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.5.RELEASE</version> </dependency> <!--CXF END-->
web.xml
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping>
cxf-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- IP地址输入拦截器 --> <bean id="ipAddressInInterceptor" class="com.auto.webservice.servlet.IpAddressInInterceptor" /> <jaxws:server id="workflow" serviceClass="com.auto.webservice.server.WorkflowService" address="/workflow"> <jaxws:serviceBean> <bean class="com.auto.webservice.server.WorkflowServiceImpl" /> </jaxws:serviceBean> </jaxws:server> </beans>
接口类
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<String, Object> map = new HashMap<String, Object>(); 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")); } } } }
效果图:
源码不解释:
private void ResultToJpg(List<Map> list, String title, HttpServletResponse response) { BufferedImage image; int totalrow = list.size(); int totalcol = 7; int imageWidth = 640; int rowheight = 40; int imageHeight = totalrow * rowheight + 105; int startHeight = 20; int startWidth = 10; int colwidth = (int) ((imageWidth - 20) / totalcol); int colwidth2 = (int) ((imageWidth - 20) / (totalcol + 1)); image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = (Graphics2D) image.getGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setColor(Color.WHITE); graphics.fillRect(0, 0, imageWidth, imageHeight); Font font = new Font("微软雅黑", Font.BOLD, 20); graphics.setFont(font); graphics.setColor(new Color(112, 48, 158)); graphics.drawString(Strings.sNull(title), startWidth, startHeight + 10); font = new Font("微软雅黑", Font.PLAIN, 13); graphics.setColor(new Color(99, 99, 99)); graphics.setFont(font); String subtitle1 = "欢迎访问"; graphics.drawString(subtitle1, startWidth, startHeight + 30); font = new Font("Arial, Helvetica, sans-serif", Font.BOLD, 13); graphics.setColor(new Color(112, 48, 158)); graphics.setFont(font); String subtitle2 = "inm.xuetang.cn"; graphics.drawString(subtitle2, startWidth + 60, startHeight + 30); font = new Font("微软雅黑", Font.PLAIN, 13); graphics.setColor(new Color(99, 99, 99)); graphics.setFont(font); String subtitle3 = "冲榜、制榜!"; graphics.drawString(subtitle3, startWidth + 165, startHeight + 30); //画首行 graphics.setColor(new Color(112, 48, 158)); graphics.fillRect(startWidth, startHeight + rowheight, imageWidth - 20, rowheight); font = new Font("微软雅黑", Font.PLAIN, 12); graphics.setColor(Color.WHITE); graphics.setFont(font); graphics.drawString("#", startWidth + 10, startHeight + rowheight * 2 - 15); graphics.drawString("公众号", startWidth + colwidth - 10, startHeight + rowheight * 2 - 15); //画表头 String[] headCells = {"发布", "总阅读数", " 头条", " 平均 ", "总点赞数", " WCI"}; for (int m = 0; m < headCells.length; m++) { graphics.drawString(headCells[m].toString(), startWidth + colwidth2 * m + colwidth * 2, startHeight + rowheight * 2 - 15); } //画行 for (int j = 0; j < totalrow; j++) { if (j % 2 == 0) { graphics.setColor(new Color(255, 255, 255)); } else { graphics.setColor(new Color(238, 238, 238)); } graphics.fillRect(startWidth, startHeight + (j + 1) * rowheight + 40, imageWidth - 20, startHeight + (j + 1) * rowheight); font = new Font("微软雅黑", Font.BOLD, 12); graphics.setColor(new Color(112, 48, 158)); graphics.setFont(font); graphics.drawString(String.valueOf(j + 1), startWidth + 10, startHeight + (j + 3) * rowheight - 15); Map map = list.get(j); font = new Font("微软雅黑", Font.PLAIN, 12); graphics.setColor(new Color(0, 0, 0)); graphics.setFont(font); graphics.drawString(Strings.sNull(map.get("wx_nickname")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 25); graphics.drawString(Strings.sNull(map.get("wx_name")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 10); graphics.drawString(Strings.sNull(map.get("url_times")) + "/" + Strings.sNull(map.get("url_num")), startWidth + colwidth2 + colwidth + 10, startHeight + (j + 3) * rowheight - 15); if (NumberUtils.toInt(Strings.sNull(map.get("url_num_10w"))) > 0) { String readnum_all = Strings.sNull(map.get("readnum_all")); int t = NumberUtils.toInt(readnum_all.substring(readnum_all.length() - 4, readnum_all.length() - 3)); if (t > 0) { readnum_all = readnum_all.substring(0, readnum_all.length() - 4) + "." + String.valueOf(t); } else { readnum_all = readnum_all.substring(0, readnum_all.length() - 4); } graphics.drawString(readnum_all + "万+", startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("readnum_all")), startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15); } if (NumberUtils.toInt(Strings.sNull(map.get("url_times_readnum"))) > 100000) { String url_times_readnum = Strings.sNull(map.get("url_times_readnum")); int t = NumberUtils.toInt(url_times_readnum.substring(url_times_readnum.length() - 4, url_times_readnum.length() - 3)); if (t > 0) { url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4) + "." + String.valueOf(t); } else { url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4); } graphics.drawString(url_times_readnum+"万+", startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("url_times_readnum")), startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15); } if (NumberUtils.toInt(Strings.sNull(map.get("readnum_av"))) > 100000) { String readnum_av = Strings.sNull(map.get("readnum_av")); int t = NumberUtils.toInt(readnum_av.substring(readnum_av.length() - 4, readnum_av.length() - 3)); if (t > 0) { readnum_av = readnum_av.substring(0, readnum_av.length() - 4) + "." + String.valueOf(t); } else { readnum_av = readnum_av.substring(0, readnum_av.length() - 4); } graphics.drawString(readnum_av+"万+", startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("readnum_av")), startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15); } graphics.drawString(Strings.sNull(map.get("likenum_all")), startWidth + colwidth2 + colwidth * 5 - 20, startHeight + (j + 3) * rowheight - 15); graphics.drawString(Strings.sNull(map.get("wci")), startWidth + colwidth2 + colwidth * 6 - 40, startHeight + (j + 3) * rowheight - 15); } //末行 graphics.setColor(Color.WHITE); graphics.fillRect(startWidth, startHeight + (totalrow + 1) * rowheight + 40, imageWidth - 20, startHeight + (totalrow + 1) * rowheight); try { response.setContentType("image/png"); OutputStream out = response.getOutputStream(); ImageIO.write(image, "png", out); } catch (Exception e) { e.printStackTrace(); } }
ComboIocLoader loader = new ComboIocLoader(
new String[]{
“*org.nutz.ioc.loader.json.JsonLoader”, “ioc/”,
“*org.nutz.ioc.loader.annotation.AnnotationIocLoader”, “cn.xuetang”}
);
ioc = new NutIoc(loader);
dao = ioc.get(Dao.class);
SELECT SUBSTRING_INDEX(SUBSTRING(url,LOCATE(“sn=”,url)+3),’&’,1),url FROM wx_kw_url_1111
项目地址: https://github.com/Wizzercn/NutzCodematic
Nutz 代码生成器:
可以生成Pojo类、Action类;
支持MySQL、Oracle、MS SQL2000、ODBC等;
classes是在jdk1.7下编译,可以直接双击 run.bat 运行。
迟迟没放出来的原因是代码写的太烂……
仅作参考。
编辑配置Nutz redis配置文件:
var ioc = { jedisConfig : { type : 'cn.xuetang.common.redis.JedisConfig', fields : { maxTotal : 200, maxIdle : 10, maxWaitMillis:10001, testOnBorrow:true, redisUrl:'127.0.0.1', redisPort:6379, redisTimeout:1000 } } }
package cn.xuetang.common.redis; /** * Created by Wizzer on 14-4-8. */ public class JedisConfig { private int maxTotal; private int maxIdle; private int maxWaitMillis; private boolean testOnBorrow; private String redisUrl; private int redisPort; private int redisTimeout;//redis断开后自动重新连接间隔时间 public int getMaxTotal() { return maxTotal; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public int getMaxIdle() { return maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public int getMaxWaitMillis() { return maxWaitMillis; } public void setMaxWaitMillis(int maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; } public boolean isTestOnBorrow() { return testOnBorrow; } public void setTestOnBorrow(boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; } public String getRedisUrl() { return redisUrl; } public void setRedisUrl(String redisUrl) { this.redisUrl = redisUrl; } public int getRedisPort() { return redisPort; } public void setRedisPort(int redisPort) { this.redisPort = redisPort; } public int getRedisTimeout() { return redisTimeout; } public void setRedisTimeout(int redisTimeout) { this.redisTimeout = redisTimeout; } }
Nutz入口类加载配置文件,config路径:
@Modules(scanPackage=true) @Ok("raw") @Fail("http:500") @IocBy(type=ComboIocProvider.class,args={ "*org.nutz.ioc.loader.json.JsonLoader","config", "*org.nutz.ioc.loader.annotation.AnnotationIocLoader","cn.xuetang"}) @SetupBy(value=StartSetup.class) @UrlMappingBy(value=UrlMappingSet.class) public class MainModule { }
初始化配置参数,新建订阅消息处理线程:
public static JedisConfig REDIS_CONFIG; //声明全局的redis连接池 public static ShardedJedisPool SHARDEDJEDIS_POOL=null; public static JedisPool JEDIS_POOL=null; public static void InitRedisConfig() {//初始化redis REDIS_CONFIG = Mvcs.ctx.getDefaultIoc().get(JedisConfig.class); JedisPoolUtil jedisPoolUtil=new JedisPoolUtil(); SHARDEDJEDIS_POOL = jedisPoolUtil.getShardedJedisPool(); JEDIS_POOL = jedisPoolUtil.getJedisPool(); } new Thread(Mvcs.getIoc().get(ImageTask.class)).start();
创建Jedis连接池工具类:
package cn.xuetang.common.redis; import cn.xuetang.common.config.Globals; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedisPool; import java.util.ArrayList; import java.util.List; /** * Created by Wizzer on 14-4-8. */ public class MyJedis { private String redisUrl; private int redisPort; public JedisPoolConfig jedisPoolConfig(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(Globals.REDIS_CONFIG.getMaxTotal()); jedisPoolConfig.setMaxIdle(Globals.REDIS_CONFIG.getMaxIdle()); jedisPoolConfig.setMaxWaitMillis(Globals.REDIS_CONFIG.getMaxWaitMillis()); jedisPoolConfig.setTestOnBorrow(Globals.REDIS_CONFIG.isTestOnBorrow()); return jedisPoolConfig; } public JedisShardInfo jedisShardInfo(){ return new JedisShardInfo(redisUrl, redisPort); } public JedisPool jedisPool(){ return new JedisPool(jedisPoolConfig(),redisUrl, redisPort); } public ShardedJedisPool shardedJedisPool(){ this.redisUrl=Globals.REDIS_CONFIG.getRedisUrl(); this.redisPort=Globals.REDIS_CONFIG.getRedisPort(); List<JedisShardInfo> jedisList = new ArrayList<JedisShardInfo>(); jedisList.add(jedisShardInfo()); return new ShardedJedisPool(jedisPoolConfig(), jedisList); } }
实现自己的监听类:
package cn.xuetang.common.redis; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.JedisPubSub; /** * 订阅监听类 * Created by Wizzer on 14-4-8. */ public class MyJedisListenter extends JedisPubSub { private final static Log log = Logs.get(); // 取得订阅的消息后的处理 public void onMessage(String channel, String message) { log.info(channel + "=" + message); } // 初始化订阅时候的处理 public void onSubscribe(String channel, int subscribedChannels) { log.info(channel + "=" + subscribedChannels); } // 取消订阅时候的处理 public void onUnsubscribe(String channel, int subscribedChannels) { log.info(channel + "=" + subscribedChannels); } // 初始化按表达式的方式订阅时候的处理 public void onPSubscribe(String pattern, int subscribedChannels) { log.info(pattern + "=" + subscribedChannels); } // 取消按表达式的方式订阅时候的处理 public void onPUnsubscribe(String pattern, int subscribedChannels) { log.info(pattern + "=" + subscribedChannels); } // 取得按表达式的方式订阅的消息后的处理 public void onPMessage(String pattern, String channel, String message) { log.info(pattern + "=" + channel + "=" + message); } }
获取单例Jedis连接池:
package cn.xuetang.common.redis; import cn.xuetang.common.config.Globals; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.JedisPool; import redis.clients.jedis.ShardedJedisPool; import java.util.Date; /** * Created by Wizzer on 14-4-8. */ public class JedisPoolUtil { private final static Log log = Logs.get(); public synchronized ShardedJedisPool getShardedJedisPool() { if (Globals.SHARDEDJEDIS_POOL == null) { MyJedis myJedis=new MyJedis(); Globals.SHARDEDJEDIS_POOL = myJedis.shardedJedisPool(); } return Globals.SHARDEDJEDIS_POOL; } public synchronized JedisPool getJedisPool() { if (Globals.JEDIS_POOL== null) { MyJedis myJedis=new MyJedis(); Globals.JEDIS_POOL = myJedis.jedisPool(); } return Globals.JEDIS_POOL; } }
数据入列同时发布订阅消息:
ShardedJedis shardedJedis=Globals.SHARDEDJEDIS_POOL.getResource(); txt.put("appid", appInfo.getId()); shardedJedis.lpush("image", Json.toJson(txt)); Jedis jedis=Globals.JEDISPOOL.getResource(); jedis.publish("newimage","true");
处理订阅消息的类:
package cn.xuetang.common.task; import cn.xuetang.common.action.BaseAction; import cn.xuetang.common.config.Globals; import cn.xuetang.common.redis.MyJedisListenter; import cn.xuetang.common.util.DateUtil; import cn.xuetang.modules.baby.bean.Baby_image; import cn.xuetang.modules.baby.bean.Baby_info; import cn.xuetang.modules.user.bean.User_conn_wx; import org.nutz.dao.Cnd; 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.lang.Strings; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.Jedis; import redis.clients.jedis.ShardedJedis; import java.util.*; /** * Created by Wizzer on 14-3-31. */ @IocBean public class ImageTask extends BaseAction implements Runnable { @Inject protected Dao dao; private final static Log log = Logs.get(); public void run() { try { log.info("ImageTask start!"); final JedisPoolUtil jedisPoolUtil = new JedisPoolUtil(); boolean isEnable = false; while (!isEnable) { try { jedisPoolUtil.getShardedJedisPool().getResource(); isEnable = true; } catch (Exception e) { log.info("The redis connection is not successful,wait " + Globals.REDIS_CONFIG.getRedisTimeout() + "ms try again."); } try { wait(Globals.REDIS_CONFIG.getRedisTimeout()); } catch (Exception e) { } } final ShardedJedis shardedJedis = jedisPoolUtil.getShardedJedisPool().getResource(); final Jedis jedis = jedisPoolUtil.getJedisPool().getResource(); MyJedisListenter listenter = new MyJedisListenter() { @Override public void onMessage(String channel, String message) { //业务代码具体实现 while (shardedJedis.exists("image")) { String data = shardedJedis.rpop("image"); } } }; jedis.subscribe(listenter, "newimage"); } catch (Exception e) { log.error(e); } } }
Request req = Request.create("http://127.0.0.1/api/user/sendtext?mykey=" + mykey, Request.METHOD.POST); JsonFormat jsonFormat=new JsonFormat(); jsonFormat.setAutoUnicode(true);//防止中文乱码,以unicode编码,根据需要设置 req.setData(Json.toJson(map,jsonFormat)); req.getHeader().set("Content-Type","application/octet-stream");//设置以字节流传送数据 Response resp = Sender.create(req).send(); if (resp.isOK()) { log.info(resp.getContent()); }
2012年9月28日,中华人民共和国住房和城乡建设部下发《关于开通12329住房公积金热线的通知》,这也苦了我们搞软件开发的程序猿们,在这里简单谈谈12329热线的建设方案。
电话热线平台其核心无非是语音自助查询和人工电话接听了,目前各地市基本上都有网上查询系统,也有一部分有自己的语音热线平台,如何充分利用现有资源实现和满足通知要求,值得思考。
图片源自:12329住房公积金热线服务导则
在满足《12329住房公积金热线服务导则》要求的原则下,充分利用住房公积金管理中心现有资源,结合12345等其他热线平台,实现12329热线功能。
即:
对于本市12345热线平台和原公积金热线都是我们公司做的话,做整合是比较理想的方案,但这里有一些问题需解决:
1)两个热线运销商不一,需协调选择最优方案;
2)12345和公积金分属不同部门单位,需地市政府协调资源;
3)从12329转出12345需要知道来源直接接入坐席,则12329需保持通话,运营商是收费的;
4)在12345热线不能判断公众是选择个人业务还是单位业务;
等等。
自建一套全新的语音平台,我公司与语音设备长期合作,已配套开发出热线业务处理平台,短信、电话、微博、传真、三方通话等等,IVR流程开发、公积金查询系统接口开发、订制功能开发等不在话下。
公司网站:http://www.hfits.com.cn
据咨询,199¥套餐赠送的200¥话费可以抵扣3G上网流量。
目前使用的套餐为集团用户:149¥-20¥的4M宽带+50¥包3G流量=每个月179¥
升级后为:199¥20M宽带赠送200¥话费可抵扣3G流量~~
月基本费 | 宽带 | iTV | 国内话费 +点对点短信 |
固话资费 | 手机资费 |
199元 | 20M (744小时) |
送全年iTV 免费观看 (标清) |
送200元话费 套餐内最多3部手机 和1部固话共享 |
区内市话:前3分钟0.2元 以后0.1元/分钟 区间市话:0.2元/分钟 长途直拨:0.29元/分钟 |
市话0.15元/分钟 长途直拨:0.29元/分钟 漫游:0.29元/分钟 全国接听免费 |
299元 | 送400元话费 套餐内最多3部手机 和1部固话共享 |
||||
399元 | 送600元话费 套餐内最多3部手机 和1部固话共享 |
||||
599元 | 送全年iTV 免费观看 (高清) |
送900元话费 套餐内最多3部手机 和1部固话共享 |
月上网流量:以上套餐都为100M/卡
【灵验:69岁现象?】:金正日(1942-2011),69岁;卡扎菲(1942-2011),69岁;萨达姆(1937-2006),69岁;苏联(1922-1991),69岁。2018… … @李以亮
来源: 方一明的日志