• 关于 asp获取url 的搜索结果

回答

这里有个asp.net的例子,但是意思大同小异,就是servlet刷出json字符串,jsp中的js部分获取这个json字符串,直接取里面各项的数据。 $("#addnum").click(function () { $.ajax({ type: 'POST', url: '/Home/ClickGood', data: obj, success: function (data) { $("#lblnum").text(data.Num); //其它操作,比如每个登录用户只能点一次,按钮禁用等 } }); });

吴孟桥 2019-12-02 02:33:53 0 浏览量 回答数 0

回答

ReAliDDNS基于云解析API的DDNSC 基于DTSDAO发布的AliDDNS 3.0继续开发至3.6.0,算是一个成熟的版本了,今天刚编译出来,分享给大家。 需要的下载吧 AliDDNS v3.6.0 v3.6.0更新内容: 1、版本号更新至3.6.0 2、著作信息放入系统托盘右键菜单“关于”。 3、增加随系统启动功能。 4、增加软件启动隐藏至托盘功能。 5、增加日志记录、超过10000行自动转储至软件目录功能。 6、软件功能实现根据使用习惯调整。 7、配置文件名称更改,参数增加。 8、完善窗体标签功能实现时的更新逻辑。 9、完善当域名记录不存在时自动添加。 10、程序代码调整,有兴趣的可以git。 ------------------------- ReAliDDNS基于云解析API的DDNSC 这个主题时间比较久了,看了一下,大家所提到的问题在v3.6.0版本已经解决。 下一个版本功能有需求的可以提提。 居然无法发表主题,没有权限,郁闷,有权限的帮忙发到新主题,可以让更多人看到、用到、反馈,谢了先! ------------------------- ReAliDDNS基于云解析API的DDNSC 再次提交一个新的版本v3.7.0.1: 1、版本号更新至3.7.0.1 2、著作信息放入系统托盘右键菜单“关于”。 3、增加随系统启动功能。 4、增加软件启动隐藏至托盘功能。 5、增加日志记录、超过10000行自动转储至软件目录功能。 6、软件功能实现根据使用习惯调整。 7、配置文件名称更改,参数增加。 8、完善窗体标签功能实现时的更新逻辑。 9、完善当域名记录不存在时自动添加。 10、增加手工指定一个IP,用于当不能从网址获取WAN口IP时救急使用。由于通过http方式从网站获取WAN口IP技术,是从返回信息过滤抓取xxx.xxx.xxx.xxx字串,有时候返回信息包含内容过多,会过滤抓取失败,因此,有必要保留一个手工指定IP的功能。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.7.1.1 1、增加系统托盘图标状态更新功能:红色-获取WAN口IP或者获取域名绑定IP失败。黄色-获取成功,但WAN口IP和域名绑定IP不一致。绿色-获取成功,WAN口IP和域名绑定IP一致。灰色-WAN口网络不通。 2、修改代码和窗体标签刷新BUG。 3、修复系统托盘图标刷新BUG。 ------------------------- 回 34楼飞翔的笨猫的帖子 ttl值使用的系统默认值,免费版本是600秒,主要是阿里云解析有好多版本,不知道修改后能否有效果,我增加一个参数,你们测试看看。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.0.0 1、增加TTL参数。 2、修复代码BUG。 ------------------------- ReAliDDNS基于云解析API的DDNSC 增加了TTL参数,请大家测试反馈信息哈。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.1.0 1、在配置文件中对accessKeyId和accessKeySecret进行加密存储。注意现有配置文件中未加密参数将失效。 ------------------------- Re回 37楼wisdomwei的帖子 引用第39楼飞翔的笨猫于2018-04-22 10:31发表的 回 37楼wisdomwei的帖子 : win10系统,勾选启动时最小化和日志自动转储 不起作用,随系统启动后,第一次无法自动绑定域名,必须手动点击立即更新一次才行 日志如下: 2018/4/22 10:28:32 运行出错!信息: System.UnauthorizedAccessException: 对注册表项“HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun”的访问被拒绝。    在 Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)    在 Microsoft.Win32.RegistryKey.CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, Object registrySecurityObj, RegistryOptions registryOptions) ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1776828][/url] 1、日志第一行报错是因为系统禁止写入注册表了,当随系统启动选定时,软件会写入系统注册表,看看是否杀毒软件拦截或者禁止了。 2、自动最小化不起作用目前无法复现错误,你再观察一下,把错误日志贴出来。 3、日志转储错误,建议使用管理员模式运行程序,有可能是文件权限原因。 如果最小化和日志转储都不起作用,建议把配置文件删除,重新运行软件,录入参数再测试保存后试一下看看是否恢复正常。 ------------------------- Re回 39楼飞翔的笨猫的帖子 引用第40楼飞翔的笨猫于2018-04-22 10:33发表的 回 39楼飞翔的笨猫的帖子 : 并且 win10 系统 设置ttl值后 无法保存设置 电脑重启后 还是回复默认600 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1776829][/url] 根据你两个帖子反馈的情况,建议你把设置文件删除,然后使用管理员模式运行一下程序,重新设置一下试试看,如果问题依旧,把错误日志贴出来看看。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.2.1 1、增加角色权限检测。 2、更多功能日志输出。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第46楼佳盟自动化于2018-04-22 17:58发表的 ReAliDDNS基于云解析API的DDNSC : 见识了  我想发链接可以吗? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1776874][/url] 可以,就是拿出来分享的哈 ------------------------- Re回 43楼wisdomwei的帖子 引用第45楼飞翔的笨猫于2018-04-22 17:17发表的 回 43楼wisdomwei的帖子 : 用了 最新的3.8.2.1版 可以自启动 设置也能保存 ddns也能自动更新,但是日志还是报错,你看下: 2018/4/22 17:06:20 计算机名: Work-PC 2018/4/22 17:06:20 当前用户: he* 2018/4/22 17:06:20 角色信息:Work-PChe* 2018/4/22 17:06:20 当前用户需要文件写入和注册表操作权限,否则相关参数不起作用! ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1776869][/url] 提示注册表访问被拒绝,原因可能是注册表访问策略被修改,或者安装了杀毒软件,例如360,把软件对注册表的访问拦截了,如果是360,看看拦截清单里面有没有,有的话就删除拦截记录,再添加一条信任记录。 如果不是360等杀毒软件,就编辑一下组策略,把当前用户对注册表访问通过。 ------------------------- ReAliDDNS基于云解析API的DDNSC 下一个版本打算增加一个自动检测升级功能,实现无人值守的自动检测升级,不用再手工替换升级版本了,目前开发中。 ------------------------- 回 50楼清者自清12的帖子 使用了c#默认的控件textbox,mask设置成了000.000.000.000,代码里面校验了不能超出255.255.255.255,使用输入时稍微将就一下,以后有时间会重新设计一下控件,默认textbox处理录入格式时比较蠢。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第53楼清者自清12于2018-06-08 13:56发表的 ReAliDDNS基于云解析API的DDNSC : 还有个,获取IP那两个网址能不能自动切换,当一个网址获取不到IP时,自动切换到另外一个网址。 软件启动过程中,当获取不到IP时,软件就会卡死好一会, [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1782201][/url] 下载最新版本,已经添加了www.net.cn获取IP的网址,当然可以自行录入地址,地址获取返回含有xxx.xxx.xxx.xxx格式的ip的,函数会自动过滤其它信息,但内容含有多个ip就会失败。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第55楼lhpdir于2018-06-13 23:08发表的 ReAliDDNS基于云解析API的DDNSC : 如果设置时间3600秒,左边显示的是360,不过10秒掉1秒,是作者有意为之? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1782899][/url] 是窗体控件格式问题,宽度不够,新版本已经增加了宽度,下载新版本即可。至于10秒掉一秒,估计是cpu时钟运行与程序控件显示不同步造成的,理论上应该是毫秒,本程序使用的是C#自带Timer控件,没有修改过。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第54楼lhpdir于2018-06-13 21:56发表的 ReAliDDNS基于云解析API的DDNSC : 解压密码? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1782895][/url] winrar压缩,不需要解压密码 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.4.0   1、增加Ngrok网络穿透功能。 2、调整倒计时控件宽度,修复当倒计时超过3位时被遮挡的问题。 3、精简代码。 ------------------------- Re回 51楼wisdomwei的帖子 引用第52楼清者自清12于2018-06-02 13:03发表的 回 51楼wisdomwei的帖子 : 兄台,whatismyip.akamai.com这个网址我这边有些地方经常获取不到IP,然后WAN口地址就变成0.0.0.0  软件能不能加一条,如果IP是0.0.0.0则不更新。要不然一获取不到IP,域名就绑定0.0.0.0了 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1781486][/url] 已经实现自主添加其他查询网址,启用自动运行时会逐个查询。 v3.8.5.0 1、设置修改实时保存。 2、可添加多个公网IP查询网址,自动运行是逐个查询,当有返回值时停止。 3、简化代码。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第53楼清者自清12于2018-06-08 13:56发表的 ReAliDDNS基于云解析API的DDNSC : 还有个,获取IP那两个网址能不能自动切换,当一个网址获取不到IP时,自动切换到另外一个网址。 软件启动过程中,当获取不到IP时,软件就会卡死好一会, [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1782201][/url] 已经实现自主添加其他查询网址,启用自动运行时会逐个查询。 v3.8.5.0 1、设置修改实时保存。 2、可添加多个公网IP查询网址,自动运行是逐个查询,当有返回值时停止。 3、简化代码。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.5.0 1、设置修改实时保存。 2、可添加多个公网IP查询网址,自动运行是逐个查询,当有返回值时停止。 3、简化代码。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.6.0   1、修改代码,.net框架版本由4.5降低到4.0,可在WinXP系统运行,WinXP系统最高支持.net 4.0。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第65楼purelyc于2018-07-21 18:44发表的 ReAliDDNS基于云解析API的DDNSC : 感谢作者的软件,请问有没有方式做成可以为域名下多个主机记录做记录值的,现在只能做一个有点浪费域名了 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1786873][/url] 你的意思是动态刷新几个A记录的IP地址吗?把几个记录刷新同一个IP地址还是不同IP地址? 或者你的意思是做一个管理域名的软件? ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第68楼qz_陈sir于2018-07-22 13:08发表的 ReAliDDNS基于云解析API的DDNSC : 楼主 发现你这个工具有个问题  用了这个工具  有设置了开机启动  其他用户远程桌面注销不了  必须把工具先退出才能注销   测了3个2003的服务器都是这样 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1786987][/url] 如果win2003服务器,建议查看一下系统日志,看看远程登录之后都执行了什么操作,最好把相关日志贴出来看看。 远程桌面注销不了这种情况第一次遇到,我试试看能否重现你说的情况。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第70楼purelyc于2018-07-22 17:21发表的 ReAliDDNS基于云解析API的DDNSC : 请问一个问题,启动后不手动点一次测试连接,域名IP就无法自动绑定 自动更新时间到达后提示 2018/7/22 17:02:25    updateDomainRecord() Exception:  Aliyun.Acs.Core.Exceptions.ClientException: InvalidParameter : The parameter value RecordId is invalid.    在 Aliyun.Acs.Core.DefaultAcsClient.ParseAcsResponse[T](AcsRequest`1 request, HttpResponse httpResponse) ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1787006][/url] 1、只有勾选了启动自动运行,软件启动才会自动分别查询阿里云DNS的A记录和WAN口IP,查询之后对比两者IP是否一致,一致就静默,等待下一次更新时间到来,不一致就立即更新。 如果没有勾选,软件启动后需要手工点击测试。 2、当返回你贴出来的日志时,说明你之前已经成功更新过A记录,但再次运行时,你只修改了域名,没有经过测试和添加到阿里云DNS,造成阿里云DNS里面的recordid对应的域名和你现在配置文件里面的不一致,正确的方法是每次修改之后都测试一下,如果不存在会提醒添加记录。 下载使用最新版本v3.8.6.0,日志记录里面会有很明确的提醒。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第73楼cxq82于2018-07-27 11:03发表的 ReAliDDNS基于云解析API的DDNSC : 帖主好! 非常感谢,开发这个插件分享给大家,这个实在找到辛苦,最终还是找到这里了。 有个疑问反馈下: 1、局域网内2机器同时开程序,更新同一域名,过会儿会无法更新域名;阿里后台发现有2个A记录,不懂是阿里故意设置的还是bug。 2、上述情况,关闭一台机器;在另一地域,用此程序更新另一个二级域名,也出现无法更新现象;是否同一key 不能多台电脑使用呢? ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1787650][/url] 1、对于同一局域网内的两台机器同时运行AliDDNS.exe,更新同一域名a.demo.com,只要录入没有问题,应该不会出现a.demo.com在阿里云DNS里面有两个recordid,请检查录入是否正确。如果问题依旧,请把两台机器的软件运行界面截图和运行日志一起贴出来,还有阿里云控制台A记录的截图,我分析一下看看是否是软件BUG。 2、不同局域网,只要WAN口IP不同,不管地域是否是否相同,更新同一域名,只会导致阿里云DNS该A记录的IP不断变化。 3、不管是否是同一局域网,同一accesskey和accesssecret,可以更新任意不同A记录的IP,如果不能成功,请检查accesskey和accesssecret是否正确,或者网络路由是否有防火墙限制,点击【测试】试一下。可以把日志贴出来看看,分析一下问题。 据我所知,目前阿里云还没有限制DNS中A记录更新的频率和次数。 我见过宽带使用长城宽带的,每次更新WAN口IP都不同,奇葩的不得了,最后ngrok网络穿透了事。 ------------------------- Re回 72楼wisdomwei的帖子 引用第75楼kakalin于2018-07-31 15:39发表的 回 72楼wisdomwei的帖子 : 帖主好,我也遇到这样的问题,随系统自动启动已经开了,但是还是要每次手动点击测试连接才能正常工作。 日志: 2018/7/31 15:31:48 计算机名: xxxx 2018/7/31 15:31:48 当前用户: xxx 2018/7/31 15:31:48 角色信息:xxxx ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1788169][/url] 关键的出错信息在这里: 2018/7/31 15:32:03 updateDomainRecord() Exception:  Aliyun.Acs.Core.Exceptions.ClientException: InvalidParameter : The parameter value RecordId is invalid. 之前已经成功运行过,阿里云DNS已经添加了域名并返回recordid了,但是,你再次启动时,配置文件里面的recordid和域名与阿里云DNS里面的recordid和域名不一致! 可能原因:1、本地修改域名后没有测试并添加。2、本地修改了recordid。3、本地配置文件被手工修改。4、阿里云DNS对应记录被手工修改。 解决办法:修改域名后点击测试和添加,确保生效,不要手工修改本地配置文件和阿里云DNS服务器里面的域名记录,除非你知道是在干什么。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第81楼鱼花于2018-08-14 20:58发表的 ReAliDDNS基于云解析API的DDNSC : 用上3.8.6版,乍么github.com/dtsdao/AliDDNS只有verson 1.0 ??? 3.8.6版在电算机重启后不会得自动点击测试连接,只能手工。要是人在外边,刚好ip又给营运商变了就不能及时更新正确ip了 补充:我的win 2012 打上自启了,能自启,就是不能解析? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1789959][/url] 原作者已经不维护更新了,我fork过来继续更新。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第82楼鱼花于2018-08-14 21:18发表的 ReAliDDNS基于云解析API的DDNSC : 018/8/14 21:08:57 计算机名: computer 2018/8/14 21:08:57 当前用户: Administrator 2018/8/14 21:08:57 角色信息:computerAdministrator 2018/8/14 21:08:57 当前用户需要文件写入和注册表操作权限,否则相关参数不起作用! ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1789962][/url] 稍后我会更新一下代码,当IP为0.0.0.0的时候不更新阿里云DNS记录,仅提示未能获取IP,需要手工获取。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第80楼服务器云于2018-08-10 22:56发表的 ReAliDDNS基于云解析API的DDNSC : 这个就是根据家里的IP 变化通过api动态的更新DNS? 有延迟么?python可以做么? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1789426][/url] 完全可以,很简单。 ------------------------- Re回 28楼wisdomwei的帖子 引用第79楼flcz于2018-08-10 16:24发表的 回 28楼wisdomwei的帖子 : 有没有获取到0.0.0.0,不修改记录的功能。我现在可能是网络原因,老被改为0.0.0.0 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1789379][/url] 稍后我会更新一下代码,当获取IP为0.0.0.0时不更新阿里云记录, 提示手工更改。 你可以尝试添加其他获取IP的地址的网址,看能否自动获取。例如:http://www.net.cn/static/customercare/yourip.asp http://ip.qq.com/ http://www.3322.org/dyndns/getip ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第78楼鱼花于2018-08-07 09:43发表的 ReAliDDNS基于云解析API的DDNSC : win 2012点击验证安钮没反应 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1788817][/url] 是“测试连接”按钮吧?点击后稍等,如果网络状况不佳,或者设置错误,会有延迟。 程序运行需要.NET FRAMEWORK 4.0以上版本。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第77楼kakalin于2018-08-01 21:07发表的 ReAliDDNS基于云解析API的DDNSC : 找到原因了,本地配置文件无法保存recordid,手动写进去以后就正常了。 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1788345][/url] 不建议修改recordid,除非你明白是在做什么?修改域名后测试连接,如果DNS记录存在,会自动获取recordid,如果不存在,会提示添加新记录。 ------------------------- Re回 72楼wisdomwei的帖子 引用第75楼kakalin于2018-07-31 15:39发表的 回 72楼wisdomwei的帖子 : 帖主好,我也遇到这样的问题,随系统自动启动已经开了,但是还是要每次手动点击测试连接才能正常工作。 日志: 2018/7/31 15:31:48 计算机名: xxxx 2018/7/31 15:31:48 当前用户: xxx 2018/7/31 15:31:48 角色信息:xxxx ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1788169][/url] 勾选随系统启动自动运行即可。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第90楼kanxiji于2018-08-18 23:34发表的 ReAliDDNS基于云解析API的DDNSC : 楼主你好 你的东西很好用, 提个建议:TTL和更新秒数可以分别设置 [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1791200][/url] 抱歉是个BUG,升级对配置文件读写时参数错误,已经修复。感谢提供建议! ------------------------- ReAliDDNS基于云解析API的DDNSC v.3.8.6.2 1、修复配置文件参数TTL和WaitingTime写入BUG。 2、增加更新逻辑,当获取WAN口IP返回0.0.0.0时,不更新阿里云DNS记录,提示手工修改。 ------------------------- ReAliDDNS基于云解析API的DDNSC v3.8.6.3 1、修改测试存储逻辑,锁定Recordid编辑框,避免添加域名成功后,手工修改造成配置文件存储Recordid与服务器不一致时造成的自动更新出错。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第94楼鱼花于2018-08-28 11:00发表的 ReAliDDNS基于云解析API的DDNSC : v3.8.6.3  ,在win2012下点测试,没能得到本地ip 勾选自启,关闭退出,重新启动,这选项是空的。 之前下载的版本,在win 2012 r2下手动还能用就是机器重启后,没能得到本机ip,要手机点测试后才正常。 ....... [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1792007][/url] 1、点击【测试连接】是测试阿里云账号信息设置是否正确,如果正确就会测试录入的域名记录是否存在,如果存在就返回recordid,如果不存在就提示添加。 2、获取本地WAN口IP点击【获取WAN口IP】按钮,而不是【测试连接】按钮。 3、如果需要自动更新,需要设置自动更新倒计时秒数,勾选自动更新,勾选随系统启动自动运行。 感觉你对软件运行界面设置不熟悉,建议详细看一下软件运行界面,配置修改日志输出框都会有提示,也详细看一下。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第96楼saoian于2018-08-30 16:02发表的 ReAliDDNS基于云解析API的DDNSC : 你好: 程序运行时提示,版本检测程序update.exe未找到,能把这个文件发出来吗? 另外在运行升级时提示,软件运行目录下没有找到updateinfo.txt,是否是直接在运行目录下新建一个updateinfo.txt文件就可了? [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1792277][/url] 抱歉自动升级功能的update.exe还有些BUG,还没有放出来,请先取消勾选【关于】菜单下的【自动检测升级】,不勾选时其它功能可正常使用,等update.exe放出来您再勾选这个功能菜单。 ------------------------- ReReAliDDNS基于云解析API的DDNSC 引用第98楼daoyuanjiao于2018-09-14 11:12发表的 ReAliDDNS基于云解析API的DDNSC : 可以具体描述一下里面的ngrok的使用吗?我的配置后一直无法访问。但是单独打开ngrok设置令牌后,启动ngrok http 80 是可以访问的!谢谢!我i一直显示“Ngrok功能启用,ngrok.exe将自动加载!本机浏览器打开:127.0.0.1:4040 查看运行状态。”但是打开127.0.0.1:4040一直显示无法访问! [url=https://bbs.aliyun.com/job.php?action=topost&tid=289624&pid=1793763][/url] ngrok的详细使用方法你从官网看一下,我这里简单说两个方法: 1、使用官网网址映射。在ngrok官网 注册一个免费账号,从官方下载编译好的ngrok.exe程序,跟AliDDNS.EXE放在一个文件夹下,然后根据页面提示,填写参数,保存,勾选后自动运行。 2、如果自己有服务器的话,从github fork一下ngrok源码到本地,直接编译一个ngrokd出来,在服务器上运行,一般运行的方式是./bin/ngrokd -tlsKey="server.key" -tlsCrt="server.crt" -domain="ngrok.xxxx.cn" -httpAddr=":8081" -httpsAddr=":8082" -tunnelAddr=":8083" &  然后再根据编译时生成的证书,编译一个win的ngrok.exe程序来,跟AliDDNS.exe放在一个文件夹下,根据服务端的配置,令牌为空,地址为:ngrok.xxx.cn:8083,要穿透的二级域名假设为demo,那么穿透后的完整URL是http://demo.ngrok.xxx.cn:8081 访问http服务, 或者https://demo.ngrok.xxx.cn:8082 访问https服务,页面是否能打开,取决于80端口上是否有服务可以访问。内网的其他服务端口也是一样,假设ftp服务跑在21端口上,穿透WAN端口是2221,那么访问URL是ftp://demo.ngrok.xxx.cn:2221,不知道说明白了吗? ------------------------- 回 102楼estas的帖子 我用的北京联通的光纤,没有任何问题。 把日志贴出来。 DDNS跟线路关系不大,阿里云是智能路由,看本地DNS设置,或者杀毒软件设置。 ------------------------- 回 100楼daoyuanjiao的帖子 不支持,仅在windows平台可用,.net3.5以上。

wisdomwei 2019-12-02 02:58:27 0 浏览量 回答数 0

问题

公司内部系统asp.net要一个接口与钉钉对接实现向用户发送消息如何做到

simonouyang 2019-12-01 21:36:36 4161 浏览量 回答数 5

新手开公司,教你化繁为简

开公司到底有没有那么难,传统的手续繁琐,线下跑断腿,场地搞不定等问题,通过阿里云”云上公司注册“解决你的烦恼。

回答

我用C#写的,已经成功了。 我说说我在此过程中遇到的问题,也许会对楼主有帮助: 首先,我在网上找的MD5(32位)加密方式有点小bug,就是比如应该是110230xxxx的给我弄成了11230xxxx,也就是奇数位的0会没有,请楼主你先在网上找个在线加密把你的密码加密一下,然后和你的密码比对一下看对不对,并且注意在发送的时候有没有空格(以防万一); 然后,一般客户端模拟登录的话ErrCode会返回-6,所以最好是先去获取一下验证码,怎么获取不用我教吧?但是注意它在输出图片的同时还在头里发了一个set-cookie(每获取一次,发给你的cookie不一样),你要把cookie保存下来,然后在登录的时候给它发回去,不然会每次都是-6; 最后,祝你早日成功。 ######回复 @CcCcCcCcd : 不管什么语言,腾讯的服务器验证的都是你发过去的消息,你确定你用户名密码正确的情况下,想想,它为什么不通过你的登录?一定是你漏发了消息。具体的可以看到第一次也是唯一一次写的博客,http://my.oschina.net/duoing/blog/147015######回复 @天体图 : 如果是用PHP写的怎么处理呢######回复 @CX-Oice : 哥们。。。已经有人问过同样的问题了,你仔细看下,我回答sorthman的。######你好,不知道怎么获取验证码.能帮忙下吗?急需,谢谢。QQ747051050######回复 @sorthman : 我获取验证码是手动识别的啊。去获取那个图片(地址你应该知道的),然后不是会有一个HttpWebResponse对象么?从这里开始,Stream reader = _HttpWebResponse.GetResponseStream(); Image img = new Bitmap(reader);然后随你怎么用了,你想保存或是用pictureBox显示在窗体上都可以######class SendMessage{ public function init($user,$password){//初始化,登陆微信平台 $url = "http://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN"; $ch=curl_init($url); $post["username"] = $user; $post["pwd"] = md5($password); $post["f"] = "json"; curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); $html = curl_exec($ch); curl_close($ch); } public function Send($content,$fromfakeid){//发送消息给指定人 $url = "http://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt '); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0'); $post['tofakeid'] = $fromfakeid; $post['type'] = 1; $post['content'] = $content; $post['ajax'] = 1; curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $html = curl_exec($ch); curl_close($ch); }############复制了你这个class 登录还是出现 -2######Java写的登录,使用MD5加密了,也设置了head,返回值不对,你知道原因么?######看一下微信的說明,返回這個消息是什麼意思######我也想问。######不知道什么原因,你解决了么######"-1":"系统错误。 "-2":"帐号或密码错误 "-3":"密码错误。" "-4":"不存在该帐户。" "-5":"访问受限。" "-6":"需要输入验证码" "-7":"此帐号已绑定私人微信号,不可用于公众平台登录。" "-8":"邮箱已存在。" "-32":"验证码输入错误" "-200":n="因频繁提交虚假资料,该帐号被拒绝登录。" "-94":"请使用邮箱登陆。" "10":"该公众会议号已经过期,无法再登录使用。" "65201":"65202":"成功登陆,正在跳转..." "0":n="成功登陆,正在跳转..." default:"未知的返回。" 这是微信平台的返回码对应错误信息。 ######回复 @MaxCrazy : 用PHP写的怎么处理呢######回复 @廖凯 : 我也是抓取不完整,看不到最末端的用户信息,怎么解决啊?######回复 @廖凯 : java环境下可以模拟登录微信公众平台,可以获取token信息,但通过http请求用户管理界面获取用户信息无法获取,原因是 httpclient 返回的html数据不完整,可能是页面字符串太多了,用抓包工具看了一下,用户信息数据正好是在body的最末端,且无法获取用户信息,有好办法么?######回复 @MaxCrazy : 这个我已经知道了,######回复 @廖凯 : 登陆的时候添加这句: post.setRequestHeader(REFERER_H, "https://mp.weixin.qq.com/"); 登陆可以解决,返回值是0,REFERER_H代表Referer字段,但是登陆后粉丝来源的页面源码发生改变,现在获取不到了。######兄弟,做出来了吗,我这里也想做一个,PHP的,验证码这里不知道怎么做,能帮帮忙吗######兄弟 我想问问你登陆那块怎么做的 为什么我这里总是返回 - 2 呢 求分享######回复 @廖凯 : 我的QQ 137978759######回复 @廖凯 :您QQ多少,我给您看一下,我写的代码,一下午了都没做出来,麻烦你帮哦我看看好吗,谢谢啦~~######验证码不用搞,重复登录几下就好了###### {"ret":"-1", "msg":"need post"} 返回这个信息 我用asp 写的,已经连 token 一起提交了 ######有哪位帅哥,用asp.net试过,有木有代码,发给我研究下咯,感激!!######http://www.oschina.net/code/snippet_146430_21868######我模拟登录的时候,老是报密码错误,请问微信的密码采用什么加密方式,有大小写之分吗

kun坤 2020-06-04 18:07:20 0 浏览量 回答数 0

回答

1.在WebBrowser中获取Cookie CookieContainer myCookieContainer = new CookieContainer(); string cookieStr = webBrowser1.Document.Cookie; string[] cookstr = cookieStr.Split(';'); foreach (string str in cookstr) { string[] cookieNameValue = str.Split('='); Cookie ck = new Cookie(cookieNameValue[0].Trim ().ToString(), cookieNameValue[1].Trim ().ToString()); ck.Domain = "www.google.com "; myCookieContainer.Add(ck); } WebClient设置cookie! WebClient wc = new WebClient(); wc.Headers.Add("Cookie", "PHPSESSID=" + cookie + ";"); // 注意,这里是Cookie,不是Set-Cookie byte[] re = wc.UploadData(Global.RootPath + "test.PHP", new byte[0]); System.Text.UTF8Encoding converter = new System.Text.UTF8Encoding(); string str = converter.GetString(re); 在WebBrowser中设置Cookie public partial class WebBrowserControl : Form { private String url; [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData); public WebBrowserControl(String path) { this.url = path; InitializeComponent(); // set cookie InternetSetCookie(url, "JSESSIONID", Globals.ThisDocument.sessionID); // navigate webBrowser.Navigate(url); } } 3.将WebBrowser的cookie信息传给HttpWebRequest 先建一个"CookieContainer" 把WebBrowser中的Cookie保存在里面 //在WebBrowser中登录cookie保存在WebBrowser.Document.Cookie中 CookieContainer myCookieContainer = new CookieContainer(); //String 的Cookie 要转成 Cookie型的 并放入CookieContainer中 string cookieStr = webBrowser1.Document.Cookie; string[] cookstr = cookieStr.Split(';'); foreach (string str in cookstr) { string[] cookieNameValue = str.Split('='); Cookie ck = new Cookie(cookieNameValue[0].Trim().ToString(), cookieNameValue[1].Trim().ToString()); ck.Domain = "www.abc.com";// 必须写对 myCookieContainer.Add(ck); } HttpWebRequest hreq = (HttpWebRequest)HttpWebRequest.Create("http://www.abc.com/search.asp "); hreq.Method = "POST"; hreq.ContentType = "application/x-www-form-urlencoded"; //自己创建的CookieContainer hreq.CookieContainer = myCookieContainer; string postdata = "id=2005&action=search&name="; byte[] byte1 = Encoding.ASCII.GetBytes(postdata); hreq.ContentLength = byte1.Length; Stream poststream = hreq.GetRequestStream(); poststream.Write(byte1, 0, byte1.Length); poststream.Close(); HttpWebResponse hres = (HttpWebResponse)hreq.GetResponse(); 转载于:https://blog.csdn.net/hkwlg1314/article/details/52187200

养狐狸的猫 2019-12-02 02:11:30 0 浏览量 回答数 0

回答

回 1楼梦丫头的帖子 网站程序是吧? ------------------------- 回 3楼dongshan8的帖子 恩,你的这个方法全英文看不懂 ------------------------- 那位大神指导下,谢谢 ------------------------- 回 6楼dongshan8的帖子 不知道是不是最下面那个,下面的内容是最下面那个的 <% '文件夹获取 '文章文件夹获取 set rs_1=server.createobject("adodb.recordset") sql="select FolderName from web_Models_type where [id]=5" rs_1.open(sql),cn,1,1 if not rs_1.eof then Article_FolderName=rs_1("FolderName") end if rs_1.close set rs_1=nothing '产品文件夹获取 set rs_1=server.createobject("adodb.recordset") sql="select FolderName from web_Models_type where [id]=6" rs_1.open(sql),cn,1,1 if not rs_1.eof then Product_FolderName=rs_1("FolderName") end if rs_1.close set rs_1=nothing '案例文件夹获取 set rs_1=server.createobject("adodb.recordset") sql="select FolderName from web_Models_type where [id]=50" rs_1.open(sql),cn,1,1 if not rs_1.eof then Case_FolderName=rs_1("FolderName") end if rs_1.close set rs_1=nothing %> <% '首页基本信息内容读取替换 set rs=server.createobject("adodb.recordset") sql="select web_name,web_url,web_image,web_title,web_keywords,web_contact,web_TopHTML,web_BottomHTML,web_description,web_copyright,web_theme from web_settings" rs.open(sql),cn,1,1 if not rs.eof and not rs.bof then web_name=rs("web_name") web_url=rs("web_url") web_image=rs("web_image") web_title=rs("web_title") web_keywords=rs("web_keywords") web_description=rs("web_description") web_copyright=rs("web_copyright") web_theme=rs("web_theme") web_consult=rs("web_contact") web_TopHTML=rs("web_TopHTML") web_BottomHTML=rs("web_BottomHTML") end if rs.close set rs=nothing %> ------------------------- 回 8楼dongshan8的帖子 哦,搞错了 <?xml version="1.0" encoding="UTF-8"?> <configuration>     <system.webServer>         <httpErrors>             <remove statusCode="500" subStatusCode="-1" />             <remove statusCode="404" subStatusCode="-1" />             <error statusCode="404" prefixLanguageFilePath="" path="C:\hzhuirong\hzhuirong\Adminhuirong\login.asp" responseMode="File" />             <error statusCode="500" prefixLanguageFilePath="" path="C:\hzhuirong\hzhuirong\Adminhuirong\login.asp" responseMode="File" />         </httpErrors>     </system.webServer> </configuration> ------------------------- 回 10楼dongshan8的帖子 好的,我改下看看,麻烦了 ------------------------- 回 10楼dongshan8的帖子 web.config文件改成你写的那样后,全站都变成500错误,没改之前只有后台的页有问题 ------------------------- 回 13楼dongshan8的帖子 改了后,点错误页跳出这个 ------------------------- 回 16楼dongshan8的帖子 好的,麻烦了 ------------------------- 回 16楼dongshan8的帖子 谢谢,问题解决了,原来是父路径没有开启

hz2016 2019-12-02 01:54:24 0 浏览量 回答数 0

问题

web应用安全防护经验小结

千鸟 2019-12-01 21:46:11 10119 浏览量 回答数 10

问题

IIS请求AccessToken报错msxml3.dll 错误80072f06

ceadelta 2019-12-01 21:23:46 4106 浏览量 回答数 2

问题

Python爬虫 湖大教学服务系统 表单提交出错:报错

kun坤 2020-06-05 22:55:06 0 浏览量 回答数 1

问题

Python爬虫 湖大教学服务系统 表单提交出错,python报错

python小菜菜 2020-05-27 15:25:43 4 浏览量 回答数 1

回答

location.非常感谢大侠!很给力~赞一个!ajax是不会刷新页面的。<preclass="brush:java;toolbar:true;auto-links:false;"><struts><packagenamespace="/"name="default"extends="struts-default"><actionname="xx"class="xx"><resultname="xx">myjsp.jsp</result></action></package></struts> 处理完后,你让它返回一个你需要的页面,然后用返回的页面覆盖当前页面就行。<preclass="brush:js;toolbar:true;auto-links:false;">$.post("xxxx.action",function(data){$("html").html(data);}); 但是这样做会导致JS代码无效救了我一命~~哈哈~谢谢啦兄弟那我测试看看哈 ajax的返回结果在js中应属于字符串,注意只是获取的返回结果,其他的事情需要我们在添加js代码。要跳转的话,可以使用window.location.href之类的函数。<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;line-height:21.988636016845703px;background-color:#FFFFFF;"> location.reload是js自有的,是为了刷新整个页面。在这里满足不了需求。 参考:<arel="nofollow">http://www.w3school.com.cn/ajax/ajax_asp_php.asp<arel="nofollow">http://www.cnblogs.com/YSO1983/archive/2010/04/06/1705169.html<arel="nofollow">http://blog.csdn.net/fangxing80/article/details/604916恩恩不错哈但是放进去,样式就改掉了 $.post(url,data,function(data){   $('body').html(data);      data={'page':1,'limit':2,'type':select_num_type};   },'html'); 用$('body'),html(data)就可以了

爱吃鱼的程序员 2020-06-22 11:34:31 0 浏览量 回答数 0

问题

服务器存在安全

3aweb 2019-12-01 19:06:08 71 浏览量 回答数 1

回答

怎么修改默认上传请求地址?######@帅狗 解决了######http://fex.baidu.com/ueditor/#qa-customurl看这里你就知道了######如果解决的啊######response.setContentType("text/html; charset=UTF-8"); 加一行这个,他获取的不是json,是html方式输出的json字符串######是因为请求超时,需要更改超时时间,如果是php,需要该php.ini中的 max_execution_time的值,如果改为0,永不过期。 php :修改php.ini中的max_execution_time值, java :tomcat中的server.xml中 找到Service下的Connector元素,在你需要访问的端口中,加入这样一个属性connectionTimeout="2000000" ######这个才是最根本的原因,希望能帮助到大家######上传失败的原因有很多,上传大小限制,php执行时间限制,内存限制,post上传最大时间限制。post_max_size=100M,upload_max_filesize=100M;max_execution_time=1200,memory_limit=256M,max_input_time=1200。###### 我当初遇到过类似的问题 不过我的原因是图片的名字是QQͼƬ20170303192544.jpg ueditor返回这个月 {"state": "SUCCESS","original": "QQ\u37c\u1ac20170303192544.jpg","size": "234692","title": "1488616354641018899.jpg","type": ".jpg","url": "/ueditor/jsp/upload/image/20170304/1488616354641018899.jpg"} original这里可能出错了吧!###### 可以参考一下这篇文章,虽然是ASP版的,但原理差不多一样: http://www.aijquery.cn/Html/UEditor/180.html

爱吃鱼的程序员 2020-05-30 21:38:48 0 浏览量 回答数 0

问题

post请求 cookie不能同步的问题? 400 报错

爱吃鱼的程序员 2020-06-01 10:26:42 0 浏览量 回答数 1

回答

怎么修改默认上传请求地址?######<atarget="_blank">@帅狗解决了######http://fex.baidu.com/ueditor/#qa-customurl看这里你就知道了######如果解决的啊######response.setContentType("text/html;charset=UTF-8");加一行这个,他获取的不是json,是html方式输出的json字符串######是因为请求超时,需要更改超时时间,如果是php,需要该php.ini中的<spanstyle="color:#000000;font-family:Monaco,Consolas,Courier,'LucidaConsole',monospace;font-size:14px;font-style:normal;font-weight:normal;line-height:21px;background-color:#FFFFFF;">max_execution_time的值,如果改为0,永不过期。 php:修改php.ini中的max_execution_time值, java:tomcat中的server.xml中<spanstyle="background-color:inherit;line-height:1.5;">找到Service下的Connector元素,在你需要访问的端口中,加入这样一个属性connectionTimeout="2000000" ######这个才是最根本的原因,希望能帮助到大家######上传失败的原因有很多,上传大小限制,php执行时间限制,内存限制,post上传最大时间限制。post_max_size=100M,upload_max_filesize=100M;max_execution_time=1200,memory_limit=256M,max_input_time=1200。###### 我当初遇到过类似的问题不过我的原因是图片的名字是QQͼƬ20170303192544.jpg ueditor返回这个月 {"state":"SUCCESS","original":"QQ\u37c\u1ac20170303192544.jpg","size":"234692","title":"1488616354641018899.jpg","type":".jpg","url":"/ueditor/jsp/upload/image/20170304/1488616354641018899.jpg"} original这里可能出错了吧!###### 可以参考一下这篇文章,虽然是ASP版的,但原理差不多一样: http://www.aijquery.cn/Html/UEditor/180.html

优选2 2020-06-09 15:34:29 0 浏览量 回答数 0

回答

<script src="~/Scripts/NewEcharts/echarts.js"></script> <script type="text/javascript"> var myChart; $(function () { load(); }); function load() { require.config({ paths: { //echarts: '../Scripts/Echartsjs' echarts: '../Scripts/NewEcharts' } }); require( [ 'echarts', 'echarts/chart/bar' //'echarts/chart/line' //'echarts/chart/map' ], DrawEchart ); } function DrawEchart(ec) { //--- 折柱 --- myChart = ec.init(document.getElementById('EchartsDiv')); //图表显示提示信息 myChart.showLoading({ text: "图表数据正在努力加载..." }); //定义图表 var option = { tooltip: { trigger: 'axis' }, //color: '#66B3FF', animation: false, addDataAnimation: false, calculable: true, xAxis: [ { type: 'value', boundaryGap: [0, 0.01] } ], yAxis: [ { splitLine: { show: false },//分隔线 //splitArea: { show: false },//分隔区域 type: 'category', // data: ['巴西', '印尼', '美国', '印度', '中国', '世界人口(万)'] data:[] } ], series: [ { name: '资源使用情况', color: '#66B3FF ', type: 'bar', // data: [18203, 23489, 29034, 104970, 131744, 630230] data:[] } ] }; //通过Ajax获取数据 $.ajax({ type: "post", async: false, //同步执行 url: "/Report/GetVMUsedInfo", dataType: "json", //返回数据形式为json data: {rnd:Math.random()}, success: function(result) { if (result) { //将返回的category和series对象赋值给options对象内的category和series //因为xAxis是一个数组 这里需要是xAxis[i]的形式 option.yAxis[0].data = result.yAxis; option.series[0].data = result.series; myChart.hideLoading(); myChart.setOption(option); } }, error: function(errorMsg) { alert("图表请求数据失败啦!"); } }); //myChart.hideLoading(); //myChart.setOption(option); } </script> 返回用的是 json数据; 后台使用的Asp.net MVC,使用了匿名类(主要是为了方便), var newObj = new { yAxis =result.Data.DanweiList, series= result.Data.ApplyVMEventList }; return Json(newObj, JsonRequestBehavior.AllowGet); 答案来源于网络

养狐狸的猫 2019-12-02 02:14:12 0 浏览量 回答数 0

回答

一、说明 只有先激活开发者模式才可以进行测试生活号相关功能 。 1、生活号激活开发者模式demo:【点击查看】 。 2、生活号官方激活文档:【点击查看】。 3、生活号支付宝后台操作地址(无需开发接口):【点击访问】。 二、普通公钥方式激活流程 1、首先点击【开发者中心】>选择生活号类型>点击生活号类型下的生活号应用进入生活号详情页>点击应用信息这一栏,到如下图页面。 注:如未创建过生活号应用,可参考【如何创建应用】说明进行创建生活号应用,再进行配置操作。 2、点击应用网关这一栏上的设置按钮,在弹出的页面上加签模式选择公钥,并且配置应用公钥内容,再保存设置,如下图所示。 注:商户应用公钥如何生成可参考【如何生成RSA2密钥】说明内容。 3、再次在当前页面点击应用网关这一栏的验证应用网关按钮,到如下图页面。 4、通过下载【生活号官方demo】,在demo上配置相关的支付宝的appid、商户公钥、商户私钥、支付宝公钥等数据(以java截图为例)。 5、demo上的数据配置成功后,(以java版demo为例)把demo放在自己的服务器上,将demo程序中GatewayServlet的访问路径写入步骤3中的应用网关输入框中(如该demo服务的外网地址为http://test.fuwuchuang.com,此时应用网关为http://test.fuwuchuang.com/fuwuchuang_demo/gateway.do)。 注1:gateway.do文件页面在php版demo对应的是Gateway.php这个页面,在.net版demo上对应的是Gateway.asp页面。 注2:如接收页面是自行编写的,必须能外网访问,并且能以post方式去接收GBK编码格式的数据内容,并且需要在接收页面进行做验签处理,验签成功后需符合给支付宝信息,详细可参考demo上的接收写法或者参考【激活开发者文档说明】,应用网关拼接方式是:外网地址+项目名称+能接收数据的文件页面。 6、把拼接好的地址填写在步骤3中页面上的应用网关这一栏上,点击确认按钮,如代码和配置的数据无误的情况下,就会显示激活成功。 三、公钥证书方式激活流程 1、首先点击【开发者中心】>选择生活号类型>点击生活号类型下的生活号应用进入生活号详情页>点击应用信息这一栏,到如下图页面。 帖子图片155.png 注:如未创建过生活号应用,可参考【如何创建应用】说明进行创建生活号应用,再进行配置操作。 2、点击应用网关这一栏上的设置按钮,在弹出的页面上加签模式选择公钥证书,并且配置应用公钥内容,再保存设置,如下图所示。 帖子图片156.png 注:公钥证书文件如何生成可参考【如何生成公钥证书】说明内容。 3、再次在当前页面点击应用网关这一栏的验证应用网关按钮,到如下图所示页面。 4、通过下载【生活号官方demo】,(以java的demo说明为例)参考demo中的GatewayServlet的文件上的代码去编写能以post方式去接收GBK编码格式的数据内容页面,并且需在该页面写证书验签的代码逻辑,详细证书验签的逻辑说明可参考【公钥证书签名验签方法】内的生活号响应返回的数据验签说明。 注1:生活号官方demo上封装的sdk版本过低会存在没有公钥证书的验签方法,需下载【服务端sdk】进行更新替换。 注2:支付宝网关会向开发者网关发送的验证消息内容请求示例如下。 REQUEST URL: http://example.com/gateway.do REQUEST METHOD: POST CONTENT:(以下数据为参与验签时传递的待签名字符串内容,验签时需对数据进行排序处理) service=alipay.service.check sign=ntjOmXFGJMdfdMnrTL5rEp9QG8d0lDEoGg3ZHvqemHeI8BlQoEsFbhEn0IfQT+pvfJz5RCuE+3Qh1X7I4z5iTIiGjDBstc0xeuiAmtP9TrJZuw2jUAODFB9qOwBJLNcWlKHUGTU/db/qRsJQCj8EjoJvSi9MRM/xKv/XmduS/C4= sign_type=RSA2 charset=GBK biz_content= 5、验签成功后需返回验签成功消息给支付宝,内容示例如下。 true 6cd4ee7e4f31c1adba2380cc65da4a3a DXr8LVfHytoZ3RR0K95pzGtA3d9LdpjIjLEis2BDIPQisPwS+FMFxZt9NCMt531EeDj/nbzoIAz8Or7PuqxNfSzNI8qnhirm/Hvr8uedXX9JiQxHu8q3Rw2lJWD8cqQzgf3xwV/+wbN8yuI7s8xjo6odq6NCqrAIu7E0DDfZyKo= RSA2 app_cert_sn值是通过解析应用公钥证书文件中签发机构名称(name)以及内置序列号(serialNumber),将二者拼接后的字符串计算MD5值获取,可参考开放平台SDK源码中AlipaySignature.getCertSN实现,如下所示。 /** * 获取证书序列号 * @param certPath X.509证书文件路径 * @return 返回证书序列号 * @throws AlipayApiException */ public static String getCertSN(String certPath) sign值是对 节点内的内容作待签名字符串进行生成,如下所示。 true 注:如何进行签名生成sign值可参考【证书签名验签】说明帖子。 6、编写完相关的页面代码后,进行拼接地址链接:外网地址+项目名称+编写好的页面(带有接收数据代码,验签代码和返回验签成功消息给支付宝代码)。 7、把拼接好的地址链接放在第3步骤截图页面上的应用网关上,点击确认按钮,如代码和配置的数据无误的情况下,就会显示激活成功。

保持可爱mmm 2020-05-07 10:56:40 0 浏览量 回答数 0

问题

安全技术百问,老板再也不用担心病毒勒索了!

yq传送门 2019-12-01 20:11:52 24648 浏览量 回答数 15

回答

  开发者们都知道在高端智能手机系统中有两种应用程序:一种是基于本地(操作系统)运行的APP;一种是基于高端机的浏览器运行的WebApp,本文将主要讲解后者。   WebApp与Native App有何区别呢?   Native App:   1、开发成本非常大。   一般使用的开发语言为JAVA、C++、Objective-C。   2、更新体验较差、同时也比较麻烦   每一次发布新的版本,都需要做版本打包,且需要用户手动更新(有些应用程序即使不需要用户手动更新,但是也需要有一个恶心的提示)。   3、非常酷   因为native app可以调用IOS中的UI控件以UI方法,它可以实现WebApp无法实现的一些非常酷的交互效果   4、Native app是被Apple认可的   Native app可以被Apple认可为一款可信任的独立软件,可以放在Apple Stroe出售,但是Web app却不行。   Web App:   1、开发成本较低   使用web开发技术就可以轻松的完成web app的开发   2、升级较简单   升级不需要通知用户,在服务端更新文件即可,用户完全没有感觉   3、维护比较轻松   和一般的web一样,维护比较简单,它其实就是一个站点   Webapp说白了就是一个针对Iphone、Android优化后的web站点,它使用的技术无非就是HTML或HTML5、CSS3、JavaScript,服务端技术JAVA、PHP、ASP。   当然,因为这些高端智能手机(Iphone、Android)的内置浏览器都是基于webkit内核的,所以在开发WEBAPP时,多数都是使用HTML5和CSS3技术做UI布局。当使用HTML5和CSS3l做UI时,若还是遵循着一般web开发中使用HTML4和CSS2那样的开发方式的话,这也就失去了WEBAPP的本质意义了,且有些效果也无法实现的,所以在此又回到了我们的主题–webapp的布局方式和技术。   哥在此说明一下,在此所说的移动平台前端开发是指针对高端智能手机(如Iphone、Android)做站点适配也就是WebApp,并非是针对普通手机开发Wap 2.0,所以在阅读本篇文章以前,你需要对webkit内核的浏览器有一定的了解,你需要对HTML5和CSS3有一定的了解。如果你已经对此有所了解,那现在就开始往下阅读吧……   1、首先我们来看看webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用   1   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />   2   <meta content="yes" name="apple-mobile-web-app-capable" />   3   <meta content="black" name="apple-mobile-web-app-status-bar-style" />   4   <meta content="telephone=no" name="format-detection" />      第一个meta标签表示:强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览;   第二个meta标签是iphone设备中的safari私有meta标签,它表示:允许全屏模式浏览;   第三个meta标签也是iphone的私有标签,它指定的iphone中safari顶端的状态条的样式;   第四个meta标签表示:告诉设备忽略将页面中的数字识别为电话号码   2、HTML5标签的使用   在开始编写webapp时,哥建议前端工程师使用HTML5,而放弃HTML4,因为HTML5可以实现一些HTML4中无法实现的丰富的WEB应用程序的体验,可以减少开发者很多的工作量,当然了你决定使用HTML5前,一定要对此非常熟悉,要知道HTML5的新标签的作用。比如定义一块内容或文章区域可使用section标签,定义导航条或选项卡可以直接使用nav标签等等。   3、放弃CSS float属性   在项目开发过程中可以会遇到内容排列排列显示的布局(见下图),假如你遇见这样的视觉稿,哥建议你放弃float,可以直接使用display:block;   4、利用CSS3边框背景属性   这个按钮有圆角效果,有内发光效果还有高光效果,这样的按钮使用CSS3写是无法写出来的,当然圆角可以使用CSS3来写,但高光和内发光却无法使用CSS3编写,   这个时候你不妨使用-webkit-border-image来定义这个按钮的样式。   -webkit-border-image就个很复杂的样式属性。   5、块级化a标签   请保证将每条数据都放在一个a标签中,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。   6、自适应布局模式   在编写CSS时,我不建议前端工程师把容器(不管是外层容器还是内层)的宽度定死。为达到适配各种手持设备,我建议前端工程师使用自适应布局模式(支付宝采用了自适应布局模式),因为这样做可以让你的页面在ipad、itouch、ipod、iphone、android、web safarik、chrome都能够正常的显示,你无需再次考虑设备的分辨率。      7、学会使用webkit-box   上一节,我们说过自适应布局模式,有些同学可能会问:如何在移动设备上做到完全自适应呢?很感谢webkit为display属性提供了一个webkit-box的值,它可以帮助前端工程师做到盒子模型灵活控制。   8、如何去除Android平台中对邮箱地址的识别   看过iOS webapp API的同学都知道iOS提供了一个meta标签:用于禁用iOS对页面中电话号码的自动识别。在iOS中是不自动识别邮件地址的,但在Android平台,它会自动检测邮件地址,当用户touch到这个邮件地址时,Android会弹出一个框提示用户发送邮件,如果你不想Android自动识别页面中的邮件地址,你不妨加上这样一句meta标签在head中   1   <meta content="email=no" name="format-detection" />      9、如何去除iOS和Android中的输入URL的控件条   你的老板或者PD或者交互设计师可能会要求你:能否让我们的webapp更加像nativeapp,我不想让用户看见那个输入url的控件条?   答案是可以做到的。我们可以利用一句简单的javascript代码来实现这个效果   1   setTimeout(scrollTo,0,0,0);      请注意,这句代码必须放在window.onload里才能够正常的工作,而且你的当前文档的内容高度必须是高于窗口的高度时,这句代码才能有效的执行。   10、如何禁止用户旋转设备   我曾经也想禁止用户旋转设备,也想实现像某些客户端那样:只能在肖像模式或景观模式下才能正常运行。但现在我可以很负责任的告诉你:别想了!在移动版的webkit中做不到!   至少Apple webapp API已经说到了:我们为了让用户在safari中正常的浏览网页,我们必须保证用户的设备处于任何一个方位时,safari都能够正常的显示网页内容(也就是自适应),所以我们禁止开发者阻止浏览器的orientationchange事件,看来苹果公司的出发点是正确的,苹果确实不是一般的苹果。   iOS已经禁止开发者阻止orientationchange事件,那Android呢?对不起,我没有找到任何资料说Android禁止开发者阻止浏览器orientationchange事件,但是在Android平台,确实也是阻止不了的。   11、如何检测用户是通过主屏启动你的webapp   看过Apple webapp API的同学都知道iOS为safari提供了一个将当前页面添加主屏的功能,按下iphoneipodipod touch底部工具中的小加号,或者ipad顶部左侧的小加号,就可以将当前的页面添加到设备的主屏,在设备的主屏会自动增加一个当前页面的启动图标,点击该启动图标就可以快速、便捷的启动你的webapp。从主屏启动的webapp和浏览器访问你的webapp最大的区别是它清除了浏览器上方和下方的工具条,这样你的webapp就更加像是nativeapp了,还有一个区别是window对像中的navigator子对象的一个standalone属性。iOS中浏览器直接访问站点时,navigator.standalone为false,从主屏启动webapp时,navigator.standalone为true, 我们可以通过navigator.standalone这个属性获知用户当前是否是从主屏访问我们的webapp的。   在Android中从来没有添加到主屏这回事!   12、如何关闭iOS中键盘自动大写   我们知道在iOS中,当虚拟键盘弹出时,默认情况下键盘是开启首字母大写的功能的,根据某些业务场景,可能我们需要关闭这个功能,移动版本webkit为input元素提供了autocapitalize属性,通过指定autocapitalize=”off”来关闭键盘默认首字母大写。      13、iOS中如何彻底禁止用户在新窗口打开页面   有时我们可能需要禁止用户在新窗口打开页面,我们可以使用a标签的target=”_self“来指定用户在新窗口打开,或者target属性保持空,但是你会发现iOS的用户在这个链接的上方长按3秒钟后,iOS会弹出一个列表按钮,用户通过这些按钮仍然可以在新窗口打开页面,这样的话,开发者指定的target属性就失效了,但是可以通过指定当前元素的-webkit-touch-callout样式属性为none来禁止iOS弹出这些按钮。这个技巧仅适用iOS对于Android平台则无效。   14、iOS中如何禁止用户保存图片\复制图片   我们在第13条技巧中提到元素的-webkit-touch-callout属性,同样为一个img标签指定-webkit-touch-callout为none也会禁止设备弹出列表按钮,这样用户就无法保存\复制你的图片了。   15、iOS中如何禁止用户选中文字   我们通过指定文字标签的-webkit-user-select属性为none便可以禁止iOS用户选中文字。   16、iOS中如何获取滚动条的值   桌面浏览器中想要获取滚动条的值是通过document.scrollTop和document.scrollLeft得到的,但在iOS中你会发现这两个属性是未定义的,为什么呢?因为在iOS中没有滚动条的概念,在Android中通过这两个属性可以正常获取到滚动条的值,那么在iOS中我们该如何获取滚动条的值呢?   通过window.scrollY和window.scrollX我们可以得到当前窗口的y轴和x轴滚动条的值。   17、如何解决盒子边框溢出   当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊的样式-webkit-box-sizing:border-box;用来指定该盒子的大小包括边框的宽度。   18、如何解决Android 2.0以下平台中圆角的问题   如果大家够细心的话,在做wap站点开发时,大家应该会发现android 2.0以下的平台中问题特别的多,比如说边框圆角这个问题吧。   在对一个元素定义圆角时,为完全兼容android 2.0以下的平台,我们必须要按照以下技巧来定义边框圆角:   1\-webkit这个前缀必须要加上(在iOS中,你可以不加,但android中一定要加);   2\如果对针对边框做样式定义,比如border:1px solid #000;那么-webkit-border-radius这属性必须要出现在border属性后。   3\假如我们有这样的视觉元素,左上角和右上角是圆角时,我们必须要先定义全局的(4个角的圆角值)-webkit-border-radius:5px;然后再依次的覆盖左下角和右下角,-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-border:0;否则在android 2.0以下的平台中将全部显示直角,还有记住!-webkit这个前缀一定要加上!   19、如何解决android平台中页面无法自适应   虽然你的html和css都是完全自适应的,但有一天如果你发现你的页面在android中显示的并不是自适应的时候,首先请你确认你的head标签中是否包含以下meta标签:   1   <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0;" />      如果有的话,那请你再仔细的看清楚有没有这个属性的值width=device-width,如果没有请立即加上吧!   20、如何解决iOS 4.3版本中safari对页面中5位数字的自动识别和自动添加样式   新的iOS系统也就是4.3版本,升级后对safari造成了一个bug:即使你添加了如下的meta标签,safari仍然会对页面中的5位连续的数字进行自动识别,并且将其重新渲染样式,也就是说你的css对该标签是无效的。   1   <meta name="format-detection" content="telphone=no" />      我们可以用一个比较龌龊的办法来解决。比如说支付宝wap站点中显示金额的标签,我们都做了如下改写:   1   <button class="t-balance"style="background:none;padding:0;border:0;">95009.00</button>元    “答案来源于网络,供您参考” 希望以上信息可以帮到您!

牧明 2019-12-02 02:17:31 0 浏览量 回答数 0

问题

从一个云盲到购买云机配置IISphp,IISJSP环境记录

苏日塔拉图 2019-12-01 21:58:15 12758 浏览量 回答数 3

回答

初识 MyBatis MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到数据库字段和记录。 MyBatis 的特点 那么 MyBatis 具有什么特点呢?或许我们可以从如下几个方面来描述 MyBatis 中的 SQL 语句和主要业务代码分离,我们一般会把 MyBatis 中的 SQL 语句统一放在 XML 配置文件中,便于统一维护。 解除 SQL 与程序代码的耦合,通过提供 DAO 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL 和代码的分离,提高了可维护性。 MyBatis 比较简单和轻量 本身就很小且简单。没有任何第三方依赖,只要通过配置 jar 包,或者如果你使用 Maven 项目的话只需要配置 Maven 以来就可以。易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 屏蔽样板代码 MyBatis 回屏蔽原始的 JDBC 样板代码,让你把更多的精力专注于 SQL 的书写和属性-字段映射上。 编写原生 SQL,支持多表关联 MyBatis 最主要的特点就是你可以手动编写 SQL 语句,能够支持多表关联查询。 提供映射标签,支持对象与数据库的 ORM 字段关系映射 ORM 是什么?对象关系映射(Object Relational Mapping,简称ORM) ,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 提供 XML 标签,支持编写动态 SQL。 你可以使用 MyBatis XML 标签,起到 SQL 模版的效果,减少繁杂的 SQL 语句,便于维护。 MyBatis 整体架构 MyBatis 最上面是接口层,接口层就是开发人员在 Mapper 或者是 Dao 接口中的接口定义,是查询、新增、更新还是删除操作;中间层是数据处理层,主要是配置 Mapper -> XML 层级之间的参数映射,SQL 解析,SQL 执行,结果映射的过程。上述两种流程都由基础支持层来提供功能支撑,基础支持层包括连接管理,事务管理,配置加载,缓存处理等。 接口层 在不与Spring 集成的情况下,使用 MyBatis 执行数据库的操作主要如下: InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession(); 其中的SqlSessionFactory,SqlSession是 MyBatis 接口的核心类,尤其是 SqlSession,这个接口是MyBatis 中最重要的接口,这个接口能够让你执行命令,获取映射,管理事务。 数据处理层 配置解析 在 Mybatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configration 对象中。之后,根据该对象创建SqlSessionFactory 对象。待 Mybatis 初始化完成后,可以通过 SqlSessionFactory 创建 SqlSession 对象并开始数据库操作。 SQL 解析与 scripting 模块 Mybatis 实现的动态 SQL 语句,几乎可以编写出所有满足需要的 SQL。 Mybatis 中 scripting 模块会根据用户传入的参数,解析映射文件中定义的动态 SQL 节点,形成数据库能执行的SQL 语句。 SQL 执行 SQL 语句的执行涉及多个组件,包括 MyBatis 的四大核心,它们是: Executor、StatementHandler、ParameterHandler、ResultSetHandler。SQL 的执行过程可以用下面这幅图来表示 MyBatis 层级结构各个组件的介绍(这里只是简单介绍,具体介绍在后面): SqlSession: ,它是 MyBatis 核心 API,主要用来执行命令,获取映射,管理事务。接收开发人员提供 Statement Id 和参数。并返回操作结果。Executor :执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成以及查询缓存的维护。StatementHandler : 封装了JDBC Statement 操作,负责对 JDBC Statement 的操作,如设置参数、将Statement 结果集转换成 List 集合。ParameterHandler : 负责对用户传递的参数转换成 JDBC Statement 所需要的参数。ResultSetHandler : 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。TypeHandler : 用于 Java 类型和 JDBC 类型之间的转换。MappedStatement : 动态 SQL 的封装SqlSource : 表示从 XML 文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的 SQL。Configuration: MyBatis 所有的配置信息都维持在 Configuration 对象之中。 基础支持层 反射模块 Mybatis 中的反射模块,对 Java 反射进行了很好的封装,提供了简易的 API,方便上层调用,并且对反射操作进行了一系列的优化,比如,缓存了类的 元数据(MetaClass)和对象的元数据(MetaObject),提高了反射操作的性能。 类型转换模块 Mybatis 的别名机制,能够简化配置文件,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现 JDBC 类型与 Java 类型的转换。在 SQL 语句绑定参数时,会将数据由 Java 类型转换成 JDBC 类型;在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型。 日志模块 在 Java 中,有很多优秀的日志框架,如 Log4j、Log4j2、slf4j 等。Mybatis 除了提供了详细的日志输出信息,还能够集成多种日志框架,其日志模块的主要功能就是集成第三方日志框架。 资源加载模块 该模块主要封装了类加载器,确定了类加载器的使用顺序,并提供了加载类文件和其它资源文件的功能。 解析器模块 该模块有两个主要功能:一个是封装了 XPath,为 Mybatis 初始化时解析 mybatis-config.xml配置文件以及映射配置文件提供支持;另一个为处理动态 SQL 语句中的占位符提供支持。 数据源模块 Mybatis 自身提供了相应的数据源实现,也提供了与第三方数据源集成的接口。数据源是开发中的常用组件之一,很多开源的数据源都提供了丰富的功能,如连接池、检测连接状态等,选择性能优秀的数据源组件,对于提供ORM 框架以及整个应用的性能都是非常重要的。 事务管理模块 一般地,Mybatis 与 Spring 框架集成,由 Spring 框架管理事务。但 Mybatis 自身对数据库事务进行了抽象,提供了相应的事务接口和简单实现。 缓存模块 Mybatis 中有一级缓存和二级缓存,这两级缓存都依赖于缓存模块中的实现。但是需要注意,这两级缓存与Mybatis 以及整个应用是运行在同一个 JVM 中的,共享同一块内存,如果这两级缓存中的数据量较大,则可能影响系统中其它功能,所以需要缓存大量数据时,优先考虑使用 Redis、Memcache 等缓存产品。 Binding 模块 在调用 SqlSession 相应方法执行数据库操作时,需要制定映射文件中定义的 SQL 节点,如果 SQL 中出现了拼写错误,那就只能在运行时才能发现。为了能尽早发现这种错误,Mybatis 通过 Binding 模块将用户自定义的Mapper 接口与映射文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作,从而避免上述问题。注意,在开发中,我们只是创建了 Mapper 接口,而并没有编写实现类,这是因为 Mybatis 自动为 Mapper 接口创建了动态代理对象。 MyBatis 核心组件 在认识了 MyBatis 并了解其基础架构之后,下面我们来看一下 MyBatis 的核心组件,就是这些组件实现了从 SQL 语句到映射到 JDBC 再到数据库字段之间的转换,执行 SQL 语句并输出结果集。首先来认识 MyBatis 的第一个核心组件 SqlSessionFactory 对于任何框架而言,在使用该框架之前都要经历过一系列的初始化流程,MyBatis 也不例外。MyBatis 的初始化流程如下 String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSessionFactory.openSession(); 上述流程中比较重要的一个对象就是SqlSessionFactory,SqlSessionFactory 是 MyBatis 框架中的一个接口,它主要负责的是 MyBatis 框架初始化操作 为开发人员提供SqlSession 对象 SqlSessionFactory 有两个实现类,一个是 SqlSessionManager 类,一个是 DefaultSqlSessionFactory 类 DefaultSqlSessionFactory : SqlSessionFactory 的默认实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。 SqlSessionManager : 已被废弃,原因大概是: SqlSessionManager 中需要维护一个自己的线程池,而使用MyBatis 更多的是要与 Spring 进行集成,并不会单独使用,所以维护自己的 ThreadLocal 并没有什么意义,所以 SqlSessionManager 已经不再使用。 ####SqlSessionFactory 的执行流程 下面来对 SqlSessionFactory 的执行流程来做一个分析 首先第一步是 SqlSessionFactory 的创建 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 1 从这行代码入手,首先创建了一个 SqlSessionFactoryBuilder 工厂,这是一个建造者模式的设计思想,由 builder 建造者来创建 SqlSessionFactory 工厂 然后调用 SqlSessionFactoryBuilder 中的 build 方法传递一个InputStream 输入流,Inputstream 输入流中就是你传过来的配置文件 mybatis-config.xml,SqlSessionFactoryBuilder 根据传入的 InputStream 输入流和environment、properties属性创建一个XMLConfigBuilder对象。SqlSessionFactoryBuilder 对象调用XMLConfigBuilder 的parse()方法,流程如下。 XMLConfigBuilder 会解析/configuration标签,configuration 是 MyBatis 中最重要的一个标签,下面流程会介绍 Configuration 标签。 MyBatis 默认使用 XPath 来解析标签,关于 XPath 的使用,参见 https://www.w3school.com.cn/xpath/index.asp 在 parseConfiguration 方法中,会对各个在 /configuration 中的标签进行解析 重要配置 说一下这些标签都是什么意思吧 properties,外部属性,这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。 <properties> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="root" /> </properties> 一般用来给 environment 标签中的 dataSource 赋值 <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> 还可以通过外部属性进行配置,但是我们这篇文章以原理为主,不会介绍太多应用层面的操作。 settings ,MyBatis 中极其重要的配置,它们会改变 MyBatis 的运行时行为。 settings 中配置有很多,具体可以参考 https://mybatis.org/mybatis-3/zh/configuration.html#settings 详细了解。这里介绍几个平常使用过程中比较重要的配置 一般使用如下配置 <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> </settings> typeAliases,类型别名,类型别名是为 Java 类型设置的一个名字。 它只和 XML 配置有关。 <typeAliases> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases> 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。 typeHandlers,类型处理器,无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。 在 org.apache.ibatis.type 包下有很多已经实现好的 TypeHandler,可以参考如下 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很方便的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。 objectFactory,对象工厂,MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。 public class ExampleObjectFactory extends DefaultObjectFactory { public Object create(Class type) { return super.create(type); } public Object create(Class type, List constructorArgTypes, List constructorArgs) { return super.create(type, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { super.setProperties(properties); } public boolean isCollection(Class type) { return Collection.class.isAssignableFrom(type); } } 然后需要在 XML 中配置此对象工厂 <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory> plugins,插件开发,插件开发是 MyBatis 设计人员给开发人员留给自行开发的接口,MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:Executor、ParameterHandler、ResultSetHandler、StatementHandler 接口,这几个接口也是 MyBatis 中非常重要的接口,我们下面会详细介绍这几个接口。 environments,MyBatis 环境配置,MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。 这里注意一点,虽然 environments 可以指定多个环境,但是 SqlSessionFactory 只能有一个,为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties); databaseIdProvider ,数据库厂商标示,MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> </databaseIdProvider> mappers,映射器,这是告诉 MyBatis 去哪里找到这些 SQL 语句,mappers 映射配置有四种方式 上面的一个个属性都对应着一个解析方法,都是使用 XPath 把标签进行解析,解析完成后返回一个 DefaultSqlSessionFactory 对象,它是 SqlSessionFactory 的默认实现类。这就是 SqlSessionFactoryBuilder 的初始化流程,通过流程我们可以看到,初始化流程就是对一个个 /configuration 标签下子标签的解析过程。 SqlSession 在 MyBatis 初始化流程结束,也就是 SqlSessionFactoryBuilder -> SqlSessionFactory 的获取流程后,我们就可以通过 SqlSessionFactory 对象得到 SqlSession 然后执行 SQL 语句了。具体来看一下这个过程‘ 在 SqlSessionFactory.openSession 过程中我们可以看到,会调用到 DefaultSqlSessionFactory 中的 openSessionFromDataSource 方法,这个方法主要创建了两个与我们分析执行流程重要的对象,一个是 Executor 执行器对象,一个是 SqlSession 对象。执行器我们下面会说,现在来说一下 SqlSession 对象 SqlSession 对象是 MyBatis 中最重要的一个对象,这个接口能够让你执行命令,获取映射,管理事务。SqlSession 中定义了一系列模版方法,让你能够执行简单的 CRUD 操作,也可以通过 getMapper 获取 Mapper 层,执行自定义 SQL 语句,因为 SqlSession 在执行 SQL 语句之前是需要先开启一个会话,涉及到事务操作,所以还会有 commit、 rollback、close 等方法。这也是模版设计模式的一种应用。 MapperProxy MapperProxy 是 Mapper 映射 SQL 语句的关键对象,我们写的 Dao 层或者 Mapper 层都是通过 MapperProxy 来和对应的 SQL 语句进行绑定的。下面我们就来解释一下绑定过程 这就是 MyBatis 的核心绑定流程,我们可以看到 SqlSession 首先调用 getMapper 方法,我们刚才说到 SqlSession 是大哥级别的人物,只定义标准(有一句话是怎么说的来着,一流的企业做标准,二流的企业做品牌,三流的企业做产品)。 SqlSession 不愿意做的事情交给 Configuration 这个手下去做,但是 Configuration 也是有小弟的,它不愿意做的事情直接甩给小弟去做,这个小弟是谁呢?它就是 MapperRegistry,马上就到核心部分了。MapperRegistry 相当于项目经理,项目经理只从大面上把握项目进度,不需要知道手下的小弟是如何工作的,把任务完成了就好。最终真正干活的还是 MapperProxyFactory。看到这段代码 Proxy.newProxyInstance ,你是不是有一种恍然大悟的感觉,如果你没有的话,建议查阅一下动态代理的文章,这里推荐一篇 (https://www.jianshu.com/p/95970b089360) 也就是说,MyBatis 中 Mapper 和 SQL 语句的绑定正是通过动态代理来完成的。 通过动态代理,我们就可以方便的在 Dao 层或者 Mapper 层定义接口,实现自定义的增删改查操作了。那么具体的执行过程是怎么样呢?上面只是绑定过程,别着急,下面就来探讨一下 SQL 语句的执行过程。 MapperProxyFactory 会生成代理对象,这个对象就是 MapperProxy,最终会调用到 mapperMethod.execute 方法,execute 方法比较长,其实逻辑比较简单,就是判断是 插入、更新、删除 还是 查询 语句,其中如果是查询的话,还会判断返回值的类型,我们可以点进去看一下都是怎么设计的。 很多代码其实可以忽略,只看我标出来的重点就好了,我们可以看到,不管你前面经过多少道关卡处理,最终都逃不过 SqlSession 这个老大制定的标准。 我们以 selectList 为例,来看一下下面的执行过程。 这是 DefaultSqlSession 中 selectList 的代码,我们可以看到出现了 executor,这是什么呢?我们下面来解释。 Executor 还记得我们之前的流程中提到了 Executor(执行器) 这个概念吗?我们来回顾一下它第一次出现的位置。 由 Configuration 对象创建了一个 Executor 对象,这个 Executor 是干嘛的呢?下面我们就来认识一下 Executor 的继承结构 每一个 SqlSession 都会拥有一个 Executor 对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为 JDBC 中 Statement 的封装版。 也可以理解为 SQL 的执行引擎,要干活总得有一个发起人吧,可以把 Executor 理解为发起人的角色。 首先先从 Executor 的继承体系来认识一下 如上图所示,位于继承体系最顶层的是 Executor 执行器,它有两个实现类,分别是BaseExecutor和 CachingExecutor。 BaseExecutor 是一个抽象类,这种通过抽象的实现接口的方式是适配器设计模式之接口适配 的体现,是Executor 的默认实现,实现了大部分 Executor 接口定义的功能,降低了接口实现的难度。BaseExecutor 的子类有三个,分别是 SimpleExecutor、ReuseExecutor 和 BatchExecutor。 SimpleExecutor : 简单执行器,是 MyBatis 中默认使用的执行器,每执行一次 update 或 select,就开启一个Statement 对象,用完就直接关闭 Statement 对象(可以是 Statement 或者是 PreparedStatment 对象) ReuseExecutor : 可重用执行器,这里的重用指的是重复使用 Statement,它会在内部使用一个 Map 把创建的Statement 都缓存起来,每次执行 SQL 命令的时候,都会去判断是否存在基于该 SQL 的 Statement 对象,如果存在 Statement 对象并且对应的 connection 还没有关闭的情况下就继续使用之前的 Statement 对象,并将其缓存起来。因为每一个 SqlSession 都有一个新的 Executor 对象,所以我们缓存在 ReuseExecutor 上的 Statement作用域是同一个 SqlSession。 BatchExecutor : 批处理执行器,用于将多个 SQL 一次性输出到数据库 CachingExecutor: 缓存执行器,先从缓存中查询结果,如果存在就返回之前的结果;如果不存在,再委托给Executor delegate 去数据库中取,delegate 可以是上面任何一个执行器。 Executor 的创建和选择 我们上面提到 Executor 是由 Configuration 创建的,Configuration 会根据执行器的类型创建,如下 这一步就是执行器的创建过程,根据传入的 ExecutorType 类型来判断是哪种执行器,如果不指定 ExecutorType ,默认创建的是简单执行器。它的赋值可以通过两个地方进行赋值: 可以通过 标签来设置当前工程中所有的 SqlSession 对象使用默认的 Executor <settings> <!--取值范围 SIMPLE, REUSE, BATCH --> <setting name="defaultExecutorType" value="SIMPLE"/> </settings> 另外一种直接通过Java对方法赋值的方式 session = factory.openSession(ExecutorType.BATCH); Executor 的具体执行过程 Executor 中的大部分方法的调用链其实是差不多的,下面是深入源码分析执行过程,如果你没有时间或者暂时不想深入研究的话,给你下面的执行流程图作为参考。 我们紧跟着上面的 selectList 继续分析,它会调用到 executor.query 方法。 当有一个查询请求访问的时候,首先会经过 Executor 的实现类 CachingExecutor ,先从缓存中查询 SQL 是否是第一次执行,如果是第一次执行的话,那么就直接执行 SQL 语句,并创建缓存,如果第二次访问相同的 SQL 语句的话,那么就会直接从缓存中提取。 上面这段代码是从 selectList -> 从缓存中 query 的具体过程。可能你看到这里有些觉得类都是什么东西,我想鼓励你一下,把握重点,不用每段代码都看,从找到 SQL 的调用链路,其他代码想看的时候在看,看源码就是很容易发蒙,容易烦躁,但是切记一点,把握重点。 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler StatementHandler 的继承结构 有没有感觉和 Executor 的继承体系很相似呢?最顶级接口是四大组件对象,分别有两个实现类 BaseStatementHandler 和 RoutingStatementHandler,BaseStatementHandler 有三个实现类, 他们分别是 SimpleStatementHandler、PreparedStatementHandler 和 CallableStatementHandler。 RoutingStatementHandler : RoutingStatementHandler 并没有对 Statement 对象进行使用,只是根据StatementType 来创建一个代理,代理的就是对应Handler的三种实现类。在MyBatis工作时,使用的StatementHandler 接口对象实际上就是 RoutingStatementHandler 对象。 BaseStatementHandler : 是 StatementHandler 接口的另一个实现类,它本身是一个抽象类,用于简化StatementHandler 接口实现的难度,属于适配器设计模式体现,它主要有三个实现类 SimpleStatementHandler: 管理 Statement 对象并向数据库中推送不需要预编译的SQL语句。PreparedStatementHandler: 管理 Statement 对象并向数据中推送需要预编译的SQL语句。CallableStatementHandler:管理 Statement 对象并调用数据库中的存储过程。 StatementHandler 的创建和源码分析 我们继续来分析上面 query 的调用链路,StatementHandler 的创建过程如下 MyBatis 会根据 SQL 语句的类型进行对应 StatementHandler 的创建。我们以预处理 StatementHandler 为例来讲解一下 执行器不仅掌管着 StatementHandler 的创建,还掌管着创建 Statement 对象,设置参数等,在创建完 PreparedStatement 之后,我们需要对参数进行处理了。 如 如果用一副图来表示一下这个执行流程的话我想是这样 这里我们先暂停一下,来认识一下第三个核心组件 ParameterHandler ParameterHandler - ParameterHandler 介绍 ParameterHandler 相比于其他的组件就简单很多了,ParameterHandler 译为参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法 ParameterHandler 只有一个实现类 DefaultParameterHandler , 它实现了这两个方法。 getParameterObject: 用于读取参数setParameters: 用于对 PreparedStatement 的参数赋值ParameterHandler 的解析过程 上面我们讨论过了 ParameterHandler 的创建过程,下面我们继续上面 parameterSize 流程 这就是具体参数的解析过程了,下面我们来描述一下 下面用一个流程图表示一下 ParameterHandler 的解析过程,以简单执行器为例 我们在完成 ParameterHandler 对 SQL 参数的预处理后,回到 SimpleExecutor 中的 doQuery 方法 上面又引出来了一个重要的组件那就是 ResultSetHandler,下面我们来认识一下这个组件 ResultSetHandler - ResultSetHandler 简介 ResultSetHandler 也是一个非常简单的接口 ResultSetHandler 是一个接口,它只有一个默认的实现类,像是 ParameterHandler 一样,它的默认实现类是DefaultResultSetHandler ResultSetHandler 解析过程 MyBatis 只有一个默认的实现类就是 DefaultResultSetHandler,DefaultResultSetHandler 主要负责处理两件事 处理 Statement 执行后产生的结果集,生成结果列表 处理存储过程执行后的输出参数 按照 Mapper 文件中配置的 ResultType 或 ResultMap 来封装成对应的对象,最后将封装的对象返回即可。 其中涉及的主要对象有: ResultSetWrapper : 结果集的包装器,主要针对结果集进行的一层包装,它的主要属性有 ResultSet : Java JDBC ResultSet 接口表示数据库查询的结果。 有关查询的文本显示了如何将查询结果作为java.sql.ResultSet 返回。 然后迭代此ResultSet以检查结果。 TypeHandlerRegistry: 类型注册器,TypeHandlerRegistry 在初始化的时候会把所有的 Java类型和类型转换器进行注册。 ColumnNames: 字段的名称,也就是查询操作需要返回的字段名称 ClassNames: 字段的类型名称,也就是 ColumnNames 每个字段名称的类型 JdbcTypes: JDBC 的类型,也就是 java.sql.Types 类型 ResultMap: 负责处理更复杂的映射关系 在 DefaultResultSetHandler 中处理完结果映射,并把上述结构返回给调用的客户端,从而执行完成一条完整的SQL语句。 内容转载自:CSDN博主:cxuann 原文链接:https://blog.csdn.net/qq_36894974/article/details/104132876?depth_1-utm_source=distribute.pc_feed.none-task&request_id=&utm_source=distribute.pc_feed.none-task

问问小秘 2020-03-05 15:44:27 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 SQL审核 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 人工智能 阿里云云栖号 云栖号案例 云栖号直播