你要有一个微信公众号,一个内网穿透工具
GET
请求 ,事件推送消息是POST
。text/plan
public void pushGet(HttpServletRequest request, HttpServletResponse response) {
String signature = request.getParameter("signature"); // 签名
String echostr = request.getParameter("echostr"); // 随机字符串
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce"); // 随机数
log.debug("signature:{}", signature);
log.debug("echostr:{}", echostr);
log.debug("timestamp:{}", timestamp);
log.debug("nonce:{}", nonce);
System.out.println("signature:" + signature);
String sha1 = getSHA1(token, timestamp, nonce);
System.out.println("sha1:" + sha1);
if (sha1.equals(signature)) {
log.debug("成功");
this.responseText(echostr, response);
}
}
public void pushPost(HttpServletRequest request, HttpServletResponse response) {
String signature = request.getParameter("signature"); // 签名
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce"); // 随机数
String sha1 = getSHA1(token, timestamp, nonce);
if (sha1.equals(signature)) {
Map<String, Object> map = null;
try {
map = XmlUtil.parseXMLToMap(request.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
log.debug("事件消息体:{}", map);
this.responseText("", response); // 回复空串,微信服务器不会对此作任何处理
}
}
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.util.*;
/**
* @description: 微信配置
* @author: Mr.Fang
* @create: 2023-05-26
**/
@Api(tags = "微信配置")
@Slf4j
@RestController
@RequestMapping("/wx/")
public class WxController {
String token="78******23";
@ApiOperation(value = "微信 token URL 验证")
@GetMapping(value = "push")
public void pushGet(HttpServletRequest request, HttpServletResponse response) {
String signature = request.getParameter("signature"); // 签名
String echostr = request.getParameter("echostr"); // 随机字符串
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce"); // 随机数
log.debug("signature:{}", signature);
log.debug("echostr:{}", echostr);
log.debug("timestamp:{}", timestamp);
log.debug("nonce:{}", nonce);
System.out.println("signature:" + signature);
String sha1 = getSHA1(token, timestamp, nonce);
System.out.println("sha1:" + sha1);
if (sha1.equals(signature)) {
log.debug("成功");
this.responseText(echostr, response);
}
}
@ApiOperation(value = "接收微信事件")
@PostMapping(value = "push")
public void pushPost(HttpServletRequest request, HttpServletResponse response) {
String signature = request.getParameter("signature"); // 签名
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce"); // 随机数
String sha1 = getSHA1(token, timestamp, nonce);
if (sha1.equals(signature)) {
Map<String, Object> map = null;
try {
// input 流返回是 xml 格式 这里转 map 了
map = XmlUtil.parseXMLToMap(request.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
log.debug("事件消息体:{}", map);
this.responseText("", response); // 回复空串,微信服务器不会对此作任何处理
}
}
/**
* 返回响应结果
*
* @param text 响应内容
* @param response
*/
public void responseText(String text, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plan;charset=UTF-8");
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
writer.write(text);
writer.flush();
writer.close();
}
/**
* 用SHA1算法生成安全签名
*
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 安全签名
*/
public String getSHA1(String token, String timestamp, String nonce) {
try {
String[] array = new String[]{token, timestamp, nonce};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 3; i++) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1签名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
signature:207e05105427e1203e769245b3860212c0ffcc56
echostr:5692172970033782203
timestamp:1685068850
nonce:499790541
signature:207e05105427e1203e769245b3860212c0ffcc56
sha1:207e05105427e1203e769245b3860212c0ffcc56
成功
打开公众号发送消息,接口就可以获取到推送事件消息内容了
{"Content":"嘻嘻嘻","CreateTime":"1685068967","ToUserName":"gh_2121212a95","FromUserName":"333333333nSg8OlaSuB0d-f8FKZo","MsgType":"text","MsgId":"24124387253374797"}
公众号配置
内网穿透
本文来自博客园,作者:天葬,转载请注明原文链接:http://www.cnblogs.com/bxmm/p/17434191.html
昨晚和一朋友J通话了许久,主要聊了聊各自的工作及目前的状态,J在某司做SLAM相关的工作,可以理解为AR,机器人,自动驾驶的方向之一,也是目前主流的趋势。说起与J的相识,也算是抱团取暖时候认识的,毕业后找工作的过程中,也许J是从知乎上看到的,或者某处转发看到的,也好像是某次留言互动的,我们就互相加了微信,从一开始到现在,有一年半的时间了,虽然没有见过面,但中间也是断断续续的交流了一些问题与想法,算是互相聊的来的那种。J入职一年多些,做着slam相关的研究和产品落地,从我们的聊天对话里,各自了解到不同公司的开发流程。下面就来说说公司里做slam是一种怎么的过程及体验。无论AR,机器人,自动驾驶,或许是同一套模板。1.研发人员会先跑通一个开源框架,我们耳熟能详的svo,vins,loam等,选其中之一进行算法移植,产品落地。2.开源框架应用的过程中肯定会存在各种bug及环境适应性,针对环境及需求修复相关bug或者增加新的feature。3.bug和feature修复完毕,一个开源框架才算真正应用到产品,也就是我们说的,第一步跑通了代码。此时,应用但手机硬件cpu或者车载硬件工控机上,软件或
对很多Mac用户来说,想用远程控制请教下大佬,太难了。在Windows上一个QQ就能搞定的事,而Mac用户几乎只能依赖Teamviewer。Teamviewer还遭到不少吐槽:占用高、打开慢,有时还因为被识别为商用而收费……现在,你不必再和它较劲了。这款名叫RustDesk的远程桌面软件火了!已经在Github上获得了6.1k颗星。这个名字已经“暴露”了它,没错,这款软件的开发语言正是Rust。 RustDesk支持多个平台,并且“安装包”只有8~9MB,相当轻量了。而且,这款软件属于半便携式,无需安装和配置,开箱即用。用户界面也是非常直观、简单: RustDesk采用的是加密直连,先尝试打洞直连,帮助两者建立连接,如果失败再通过服务器转发。 它支持跨平台传输文件。比如,Mac和Windows电脑之间进行文件传输时,界面长这样:RustDesk开发者还是一位中国程序员,当然软件也支持中文版。 苦远程久矣的我,上手试了一下,下载安装一气呵成。打开后,界面的确非常清爽,大概是这样: 注意:公共服务器目前是不支持修改ID的。 从去年开始,作者已经开始不断更新软件版本。有不少网友表示:软件体积
注:本文系原创投稿本文以api.mingongge.com.cn域名为测试对象进行统计,日志为crm.mingongge.com.cn和risk.mingongge.com.cn请求之和(此二者域名不具生产换环境统计意义),生产环境请根据具体需要统计的域名进行统计。由于涉及生产线上服务器,故本文部分服务器IP做了打码处理。一、服务介绍1.1、ELKELK是三个开源软件的缩写,分别表示:Elasticsearch,Logstash,Kibana,它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。Logstash主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,ser
5月18日国际博物馆日 文末揭晓13项博物馆“黑科技”哟~ ↓随着《国家宝藏》的热播以及故宫文化资源走进平常人家高冷的博物馆“热”起来大英博物馆台北故宫博物馆故宫博物院…你是否lost在硕大的博物馆之中在万千藏品中不知道何去何从△博物馆的秘密逛了好半天离开时才发现没见馆藏珍宝踪迹仅疲于捕捉各个展品的文字介绍想寻求“贴身”导游边走边讲的便捷…传统的逛馆模式已经out博物馆得智慧化 再智慧化一点!△智慧化博物馆5月18国际博物馆日,云南省文物局和“游云南”、博物官联合打造云南数字博物馆平台上线,初期上线110个博物馆,“游云南数字博物馆平台”用13项“黑科技”颠覆博物馆体验,一部手机足不出户就能游遍云南的博物馆,智慧化一步到位,让文物“活”起来了!现场还举行了《云南文博数字开放平台建设战略合作协议》签约仪式等多项活动。△签约仪式云南省文化和旅游厅副厅长、省文物局局长杨德聪,云南省文化和旅游厅党组成员、省纪委驻厅纪检组组长邱旗,云南省文化和旅游厅巡视员文淑琼,云南省博物馆馆长马文斗,云南腾云信息产业有限公司总裁、一部手机游云南项目总负责人舒展博士,腾讯浏览平台产品部总经理叶骏,腾讯浏览平台产
知道的越多,不知道的就越多,业余的像一棵小草!编辑:业余草 来源:https://www.xttblog.com/?p=4996前言MQ的主要特点为解耦、异步、削峰,该文章主要记录与分享个人在实际项目中的RocketMQ削峰用法,用于减少数据库压力的业务场景,其中RocketMQ的核心组件概念如下:Producer:生产发送消息Broker:存储Producer发送过来的消息Consumer:从Broker拉取消息并进行消费NameServer:为Producer或Consumer路由到Broker其中消费流程有以下几点是必须注意的:RocketMQ的Consumer获取消息是通过向Broker发送拉取请求获取的,而不是由Broker发送Consumer接收的方式。Consumer每次拉取消息时消息都会被均匀分发到消息队列再进行传输,所以RocketMQ中的很多参数都是针对队列而不是Topic的(这个是重点,顺便吐槽下源码的文档讲的真不清晰,很多都需要自己试错,但Dashboard做得很好),其中每个Broker消息队列(ConsumeQueue)的数量都可以通过RocketMQDas
参考bash少见的用法http://blog.csdn.net/wonderisland/article/details/22892759。原有项目里自带的启动脚本用到了bash_source获取脚本名称,最后使用如下方式启动程序。nohupnice-n$APP_NICENESS"${this}"$command"$@">"$log"2>&1</dev/null&然而发现有的同学调用后会报出nice:.....:Nosuchfileordirectory之类的错误参考线上脚本写了一个测试shell名为testbashsourcethis="${BASH_SOURCE-$0}"echo$thisbin=`dirname"$0"`echo$binbin=`cd"$bin";pwd`echo$binAPP_HOME=`dirname"$bin"`echo$APP_HOME使用几种不同的方式启动脚本:17:53[root@
如果正在运行一个transaction,这个时候系统有一个transportrequestimport进来,这个TR包含了一些DDICobject的change,并且这些DDICobject正在被当前transaction使用,就会出现这个exception:SAP的建议是在晚上user很少的时候importTR。用SGEN只能通过在userlaunchtransaction之前预先生成最新的ABAPLOAD来避免这个问题,但是对于TRimport之前已经load到memory开始执行的transaction则无能为例。Hybris不会遇到类似的问题,因为其datatype分为designtimesource和runtimeartifact两种:(1)Thereisafile-basedrepresentationthatisspreadacrossinthevariousitems.xmlfilesofHybrisextensions.ThisrepresentationisnotactivelyusedbyHybrisatruntime.Youcanmodifythisrepres
背景介绍今天我要回顾并强化概念。为此,我们要进行两项探索首先,我们会编码一个基本管道进行监督学习。我会向大家展示多个分类器如何解决同一个问题。然后,我们要锐化直觉关于一个算法从数据中学习的真正含义,因为尽管听起来这很魔幻,实际上一点也不。为了扫平障碍,我们来看一个常见的你可能想要进行的实验。想象你在建立一个垃圾邮件分类器。这仅仅是一个功能,把刚收到的邮件标记为垃圾邮件或正常邮件。现在,你已经收集了一些数据,这已经为训练一个模型做好准备。但在使用它之前,首先需要回答一个问题:这个模型究竟可以做到多准确?如果用它来分类你的数据中没有的邮件。我们希望在使用它之前尽可能地确认模型工作正常。我们可以通过一个实验来帮助检验这一点。一个办法是把已有的数据分成两部分。我们称之为训练数据和测试数据。我们用训练数据来训练我们的模型,使用测试数据来测试模型在新数据上运行的准确度。这是一个常见的模式,让我们来看看怎么用代码实现。为了扫除障碍,我们从scikit中导入数据集。我们要再次用Iris,它的数据已经包含其中非常方便。但我们之前没有见到的是我将两个术语称作特征x与标签y。为什么呢?这是因为看待分类器的一
在spring管理的web项目里,譬如Struts和spring的项目,配置好后,Struts里就可以直接使用定义好的service。但是如果要在普通的工具类里,使用service或dao,就会报空指针,因为这个普通的Java类并不在spring管理下,不能使用spring注入的service。下面讲一个方法,让普通工具类也能使用service。定义一个类SpringTool/** *通过该类即可在普通工具类里获取spring管理的bean *@authorwolf * */ publicfinalclassSpringToolimplementsApplicationContextAware{ privatestaticApplicationContextapplicationContext=null; @Override publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{ if(SpringTool.applicationContext==n
导读本文从复杂网络的研究简史出发,简单介绍了复杂网络的基本特征、几种基本的网络模型、网络挖掘方法以及在信贷反欺诈中的应用。来源:ZRobot零机科技丨作者:Joey数据猿官网|www.datayuan.cn 今日头条丨一点资讯丨腾讯丨搜狐丨网易丨凤凰丨阿里UC大鱼丨新浪微博丨新浪看点丨百度百家丨博客中国丨趣头条丨腾讯云·云+社区近年来,随着科学技术的飞速发展,人类的生产和生活日益离不开各种各样的网络,我们已经步入了网络化时代。当我们拿起手机给家人、朋友或者同事拨打电话时,就在不知不觉中参与到了社交网络形成的过程中;当我们登上高铁或者飞机时,就可以享受交通网络给我们带来的方便;即使当我们躺在床上什么也不干时,大脑中的神经元们也会形成巨大的复杂网络相互传递信号,帮助我们思考或者行动。网络化时代让人与人之间的关系更加紧密,也给人类的生活带来的极大的便捷。今天小Z就邀请ZRobot计量分析师Joey(研究方向:复杂网络)从以下几个方面跟大家分享复杂网络以及复杂网络的应用:·复杂网络的研究简史·复杂网络的统计特征·常见的复杂网络模型·网络挖掘——链路预测·网络挖掘——社团结构·利用复杂网络进行信
HMI与828D系统之间的通信视频内容1.设置828DX130(在屏幕后面)工厂网络IP地址上图,在诊断菜单,选择”TCP/IP总线”.选择右侧的”TCP/IP诊断”。上图选择”更改”,这里连接好之后需要手动刷新一次,直到平均可用性为100%才可以。选择”手动”,并输入IP地址和子网掩码。并”确定”。上图,可以ping通828DX130口2.WINCCV14HMI设置电脑PGPC接口设置为,S7ONLINE连接。在WINCCV14添加新设备,选择”HMI”,精简系列10寸PN屏。上图,添加新的连接。选择”S7-300/400”,输入HMI的IP地址和828DX130口的IP地址。建立新变量mxz1整数类型,地址MW40在画面添加IO域,并连接到变量mxz1。然后保存并编译。启动HMI仿真,输入22。上图可以看到,828D数控诊断里面,MW40已经变为22.通讯正常
位运算符有三个:“与(&)”、“或(|)”、“异或(^)”。在了解位运算符之前,请先复习逻辑运算符: 小朋友学C语言(12):逻辑运算符位运算,就是对应的bit参与运算,结果是整型数。 逻辑运算,是两个逻辑变量(0或1,非0都算做1)参与运行,结果是逻辑值(0或1)。(一)位运算符“与”(&)运算规则: 1&1=1 1&0=0 0&1=0 0&0=0例1:13&6=4注意:13在计算机里实际占32位,在1101的左边还有28个0,为了表示简便,将左侧的28个0都省略了。 同样,6的二制式形式0100的最左边也有28个0。编程验证:#include<stdio.h> intmain() { inta=13; intb=6; intresult=a&b; printf("%d&%d=%d\n",a,b,result); return0; }复制运行结果:13&6=4复制(二)位运算符“或”(|)运算规则: 1|1=1 1|0=1 0|1=1 0|0=0例2:13|2=15程序
ApacheStruts2是一个基于MVC设计模式的Web应用框架,会对某些标签属性(比如id)的属性值进行二次表达式解析,因此在某些场景下将可能导致远程代码执行。 Struts2特征: 通过页面回显的错误消息来判断,页面不回显错误消息时则无效。 通过网页后缀来判断,如.do .action,有可能不准。 判断/struts/webconsole.html是否存在来进行判断,需要devMode为true。 漏洞影响版本: 影响版本 S2-001 Struts2.0.0-2.0.8 S2-005 Struts2.0.0-2.1.8.1 S2-007 Struts2.0.0-2.2.3 S2-008 Struts2.1.0–2.3.1 S2-009 Struts2.1.0-2.3.1.1 S2-012 Struts2.1.0-2.3.13 S2-015 Struts2.0.0-2.3.14.2 S2-016 Struts2.0.0–2.3.15 S2-019 Struts2.0.0-2.3.15.1 S2-
1.过滤用户可能值其搜索条件的起始或结束位置不小心输入的空白字符:应用trim();2.转义数据(第4章)函数:addslashes(),stripslashes(),get_magic_quotes_gpc();3.在脚本中连接MySQL服务器:mysqli(…,…,…,…); //面向对象的方法(实例化一个对象) @$db=newmysqli(‘localhost’,’bookorama’,’bookorama123’,’books’); //面向过程的方式 @$db=mysqli_connect(‘localhost’,’bookorama’,’bookorama123’,’books’); //测试连接的结果的函数:mysqli_connect_errno()4.从Web连接数据库:  
insertintotable(id,name,age)values(1,"A",19)onduplicatekeyupdatename=values(name),age=values(age) 复制 /*插入数据:如果有重复的则选择更新;*/ insertignoreinto`testtable`(`mpass`,`pass`)selectmpass,passfromrr_pass_0limit0,1000000 replaceinto`testtable`(`mpass`,`pass`)selectmpass,passfromrr_pass_0limit0,10 复制 //设置主键:如果有重复的数据选择丢弃; select*,count(distinctname)fromtablegroupbyname 复制 //查询出重复的数据 这几天写了个导入脚本;留个笔记; <?php error_reporting(0); ini_set('memory_limit','1024M'); header('Content-type:text/html
目录背景说明方案实现 背景说明 在早期生产环境尝试使用docker的时候,虽然使用了harbor作为镜像仓库,但是并没有做好相关存储规划,所有的镜像都直接存储到了harbor本地。随着业务发展,本地存储已无法满足镜像存储需求。 解决方案有两种: 使用共享文件系统存储,比如glusterfs,直接挂载本地的harbor存储目录当中。在此之前,只需要先把harbor本地目录中的文件拷贝到glusterfs当中即可。 部署一套新的harbor,直接使用共享存储作为镜像后端存储。将现有harbor中的所有镜像全量同步到新的harbor当中。 这两种方式操作起来从复杂度上来讲,都还好。但我们线上glusterfs面临下线。所以选择了第二种方式。 第二种方式,其实就是找一台新的机器,部署一套新的harbor,直接使用新的存储,无论是文件系统也好,对象存储也罢。然后使用harbor自带的主从复制即可完成镜像的全量同步。在此过程中,甚至不用停机。 但是,第二种方式,要求新部署的harbor版本与原harbor版本一致。我们原来的harbor版本比较低,而且很久没升级了,我这人有强迫症,觉得既然要搞
AndroidStudio增量升级什么情况下使用最合适呢? 比如现在的as版本是2.2版本,而你的as版本2.0版本,这个时候点CheckForUpdates就没有反应了,因为你已经2个有版本没升级了(版本跨度太大 ),所以这样就不能在线升级了。 重要的信息 谷歌更新地址:https://dl.google.com/android/studio/patches/updates.xml 增加升级Jar下载:(windodws为win—linux为unix—macos为mac。对号入座) https://dl.google.com/android/studio/patches/AI-xx-xx-patch-win.jar https://dl.google.com/android/studio/patches/AI-xx-xx-patch-mar.jar https://dl.google.com/android/studio/patches/AI-xx-xx-patch-unix.jar
一fact变量 1.1 fact简介 ansible有一个模块叫setup,用于获取远程主机的相关信息,并可以将这些信息作为变量在playbook里进行调用。而setup模块获取这些信息的方法就是依赖于fact。 [root@node1ansible]#ansibledemo2.example.com -msetup demo2.example.com|SUCCESS=>{ "ansible_facts":{ "ansible_all_ipv4_addresses":[ "192.168.132.132" ], "ansible_all_ipv6_addresses":[ "fe80::6a92:62ba:1b33:c93d" ], "ansible_apparmor":{ "status":"disabled" }, "ansible_architecture":"x86_64", "ansible_bios_date":"04/13/2018", "ansible_bios_version":"6.00", "ansible_cmdline":{ "B
一、其他 1、System.in、System.out(标准输入、输出流) System.in:标准的输入流,默认从键盘输入。 System.out:标准的输出流,默认从控制台输出。 改变标准输入输出(System下的静态方法)。 voidsetIn(InputStreamin):重新分配"标准"输入流 voidsetOut(PrintStreamout):重新分配"标准"输出流 2、PrintStream、PrintWriter(打印流) 代码示例:将内存数据打印到文件 1publicclassMain{ 2publicstaticvoidmain(String[]args){ 3try{ 4FileOutputStreamfos=newFileOutputStream(newFile("F:\\hello.txt")); 5 6//创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新输出缓冲区) 7PrintStreamps=newPrintStream(fos,true); 8 9//把标准输出流(控制台输出)改成文件 10Syste