首页 文章 精选 留言 我的

精选列表

搜索[药械客户管理],共10000篇文章
优秀的个人博客,低调大师

okhttps v2.4.5 已经发布,轻量级 HTTP 客户端

okhttps v2.4.5 已经发布 此版本更新内容包括: 1、Websocket 新增 status() 方法 2、WebSocketTask 新增 isConnected() 方法,可判断连接是否已建立 3、抽象 DataSet(只读数据集)接口,Mapper 和 Array 为其子接 4、优化文件下载控制部分代码 因上版发布比较仓促,建议 v2.4.4 都升级到 v2.4.5 详情查看:https://gitee.com/ejlchina-zhxu/okhttps/releases/v2.4.5

优秀的个人博客,低调大师

gout v0.1.2 发布,Golang 实现的 http 客户端

项目地址 https://gitee.com/guonaihong/gout https://github.com/guonaihong/gout changlog #241上传进度(在v0.0.4版本中间件里面实现https://github.com/antlabs/gout-middleware) #248调整FormFile和FormType的优先级 #250新增关闭301中间件 上传进度条 currBytes是已经上传数据,totalBytes是数据总大小. currBytes/totalBytes就是上传进度百分比 package main import ( "bytes" "github.com/antlabs/gout-middleware/request" "github.com/guonaihong/gout" ) func main() { gout.POST(":8080").RequestUse(request.ProgressBar(func(currBytes, totalBytes int) { fmt.Printf("%d:%d-->%f%%\n", currBytes, totalBytes, float64(currBytes)/float64(totalBytes)) })).SetBody(strings.Repeat("1", 100000) /*这里构造大点的测试数据,使用时换成真实业务数据,就可以看到效果*/).Do() }

优秀的个人博客,低调大师

gout v0.1.0 发布,golang 实现的 http 客户端

项目地址 https://gitee.com/guonaihong/gout https://github.com/guonaihong/gout changlog #226bench:设置Rate(压测频率),Number和Duration会有误差(pr:#227) #231明确SetBody, BindBody传递nil指针返回错误(pr:#232) #235请求中间件设计(pr:#236) #234新增gzip压缩请求body功能 #233打开debug模式,http.Header数据里面有%号效果优化(pr:#239) 重要特性(加入请求中间件设计) 请求中间件地址 https://github.com/antlabs/gout-middleware 请求中间件example 请求body使用gzip压缩 import ( "github.com/antlabs/gout-middleware/request" "github.com/guonaihong/gout" ) func main() { gout.POST(":6666/compress"). RequestUse(request.GzipCompress()). SetBody("hello world"). Do() }

优秀的个人博客,低调大师

Seata 客户端需要同时启动 TM 和 RM 吗?

在分析启动部分源码时,我发现 GlobalTransactionScanner 会同时启动 RM 和 TM client,但根据 Seata 的设计来看,TM 负责全局事务的操作,如果一个服务中不需要开启全局事务,此时是不需要启动 TM client的,也就是说项目中如果没有全局事务注解,此时是不是就不需要初始化 TM client 了,因为不是每个微服务,都需要 GlobalTransactional,它此时仅仅作为一个 RM client 而已。 于是我着手将 GlobalTransactionScanner 稍微更改了初始化的规则,由于之前 GlobalTransactionScanner 调用 初始化方法是在 InitializingBean 中的 afterPropertiesSet() 方法中进行,afterPropertySet() 仅仅是当前 bean 初始化后被调用,此时无法得知当前 Spring 容器是否有全局事务注解。 因此我去掉了 InitializingBean,改成了是实现 ApplicationListener,在实例化 bean 的过程中检查是否有 GlobalTransactional 注解的存在,最后在 Spring 容器初始化完成之后再调用 RM 和 TM client 初始化方法,这时候就可以根据项目是否有用到全局事务注解来决定是否启动 TM client 了。 这里附上 PR 地址:https://github.com/seata/seata/pull/1936 随后在 pr 中讨论中得知,目前 Seata 的设计是只有在发起方的 TM 才可以发起 GlobalRollbackRequest,RM 只能发送 BranchReport(false) 上报分支状态个 TC 服务端,无法直接发送 GlobalRollbackRequest 进行全局回滚操作。具体的交互逻辑如下: 那么根据上面的设计模型,自然可以按需启动 TM client 了。 但是 Seata 后面的优化迭代中,还需要考虑的一点是: 当 Provider 服务出现异常时,是否可以直接由 Provider 的 TM client 发起全局回滚?这也就意味着可以缩短分布式事务的周期时间,尽快释放全局锁让其他数据冲突的事务尽早的获取到锁执行。 也就是说在一个全局事务当中,只要有一个 RM client 执行本地事务失败了,直接当前服务的 TM client 发起全局事务回滚,不必要等待发起方的 TM 发起的决议回滚通知了。如果要实现这个优化,那么就需要每个服务都需要同时启动 TM client 和 RM client。 更多精彩文章请关注作者维护的公众号「后端进阶」,这是一个专注后端相关技术的公众号。 关注公众号并回复「后端」免费领取后端相关电子书籍。 欢迎分享,转载请保留出处。

优秀的个人博客,低调大师

开源中国客户端 Android 10 经验适配指南,含代码

我们App的适配从 targetSdkVersion = 26跨版本升级到29,因此会遇到大量的坑,最终的版本配置如下: 现在进入填坑适配指南,包含实际经验代码,绝不照搬翻译文档 1.Region.Op相关异常:java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed 当targetSdkVersion >=Build.VERSION_CODES.P 时调用 canvas.clipPath(path, Region.Op.XXX); 引起的异常,参考源码如下: @Deprecated public boolean clipPath(@NonNull Path path, @NonNull Region.Op op) { checkValidClipOp(op); return nClipPath(mNativeCanvasWrapper, path.readOnlyNI(), op.nativeInt); } private static void checkValidClipOp(@NonNull Region.Op op) { if (sCompatiblityVersion >= Build.VERSION_CODES.P && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) { throw new IllegalArgumentException( "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed"); } } 我们可以看到当目标版本从Android P开始,Canvas.clipPath(@NonNull Path path, @NonNull Region.Op op) ; 已经被废弃,而且是包含异常风险的废弃API,只有Region.Op.INTERSECT 和 Region.Op.DIFFERENCE 得到兼容,目前不清楚google此举目的如何,仅仅如此简单就抛出异常提示开发者适配,几乎所有的博客解决方案都是如下简单粗暴: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { canvas.clipPath(path); } else { canvas.clipPath(path, Region.Op.XOR);// REPLACE、UNION 等 } 但我们一定需要一些高级逻辑运算效果怎么办?如小说的仿真翻页阅读效果,解决方案如下,用Path.op代替,先运算Path,再给canvas.clipPath: if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){ Path mPathXOR = new Path(); mPathXOR.moveTo(0,0); mPathXOR.lineTo(getWidth(),0); mPathXOR.lineTo(getWidth(),getHeight()); mPathXOR.lineTo(0,getHeight()); mPathXOR.close(); //以上根据实际的Canvas或View的大小,画出相同大小的Path即可 mPathXOR.op(mPath0, Path.Op.XOR); canvas.clipPath(mPathXOR); }else { canvas.clipPath(mPath0, Region.Op.XOR); } 2.明文HTTP限制 当targetSdkVersion >=Build.VERSION_CODES.P 时,默认限制了HTTP请求,并出现相关日志: java.net.UnknownServiceException: CLEARTEXT communication to xxx not permitted by network security policy 第一种解决方案:在AndroidManifest.xml中Application添加如下节点代码 <application android:usesCleartextTraffic="true"> 第二种解决方案:在res目录新建xml目录,已建的跳过 在xml目录新建一个xml文件network_security_config.xml,然后在AndroidManifest.xml中Application添加如下节点代码 android:networkSecurityConfig="@xml/network_config" 名字随机,内容如下: <?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config> 3.Android Q(10)中的媒体资源读写 相关的Android Q 行为变更不做细说,网上大部分博客关于Android Q 适配都在说行为变更,我们将根据实际遇到的问题,实际解决 1、扫描系统相册、视频等,图片、视频选择器都是通过ContentResolver来提供,主要代码如下: private static final String[] IMAGE_PROJECTION = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media._ID, MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME}; Cursor imageCursor = mContext.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, null, null, IMAGE_PROJECTION[4] + " DESC"); String path = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[0])); String name = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[1])); int id = imageCursor.getInt(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[2])); String folderPath = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[3])); String folderName = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[4])); //Android Q 公有目录只能通过Content Uri + id的方式访问,以前的File路径全部无效,如果是Video,记得换成MediaStore.Videos if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ path = MediaStore.Images.Media .EXTERNAL_CONTENT_URI .buildUpon() .appendPath(String.valueOf(id)).build().toString(); } 2、判断公有目录文件是否存在,自Android Q开始,公有目录File API都失效,不能直接通过new File(path).exists();判断公有目录文件是否存在,正确方式如下: public static boolean isAndroidQFileExists(Context context, String path){ if (context == null) { return false; } AssetFileDescriptor afd = null; ContentResolver cr = context.getContentResolver(); try { Uri uri = Uri.parse(path); afd = cr.openAssetFileDescriptor(Uri.parse(path), "r"); if (afd == null) { return false; } else { close(afd); } } catch (FileNotFoundException e) { return false; }finally { close(afd); } return true; } 3、保存或者下载文件到公有目录,保存Bitmap同理,如Download,MIME_TYPE类型可以自行参考对应的文件类型,这里只对APK作出说明 public static void copyToDownloadAndroidQ(Context context, String sourcePath, String fileName, String saveDirName){ ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME, fileName); values.put(MediaStore.Downloads.MIME_TYPE, "application/vnd.android.package-archive"); values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/" + saveDirName.replaceAll("/","") + "/"); Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI; ContentResolver resolver = context.getContentResolver(); Uri insertUri = resolver.insert(external, values); if(insertUri == null) { return; } String mFilePath = insertUri.toString(); InputStream is = null; OutputStream os = null; try { os = resolver.openOutputStream(insertUri); if(os == null){ return; } int read; File sourceFile = new File(sourcePath); if (sourceFile.exists()) { // 文件存在时 is = new FileInputStream(sourceFile); // 读入原文件 byte[] buffer = new byte[1444]; while ((read = is.read(buffer)) != -1) { os.write(buffer, 0, read); } is.close(); os.close(); } } catch (Exception e) { e.printStackTrace(); } finally { close(is,os); } } 4、保存图片相关 /** * 通过MediaStore保存,兼容AndroidQ,保存成功自动添加到相册数据库,无需再发送广告告诉系统插入相册 * * @param context context * @param sourceFile 源文件 * @param saveFileName 保存的文件名 * @param saveDirName picture子目录 * @return 成功或者失败 */ public static boolean saveImageWithAndroidQ(Context context, File sourceFile, String saveFileName, String saveDirName) { String extension = BitmapUtil.getExtension(sourceFile.getAbsolutePath()); ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DESCRIPTION, "This is an image"); values.put(MediaStore.Images.Media.DISPLAY_NAME, saveFileName); values.put(MediaStore.Images.Media.MIME_TYPE, "image/png"); values.put(MediaStore.Images.Media.TITLE, "Image.png"); values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + saveDirName); Uri external = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; ContentResolver resolver = context.getContentResolver(); Uri insertUri = resolver.insert(external, values); BufferedInputStream inputStream = null; OutputStream os = null; boolean result = false; try { inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); if (insertUri != null) { os = resolver.openOutputStream(insertUri); } if (os != null) { byte[] buffer = new byte[1024 * 4]; int len; while ((len = inputStream.read(buffer)) != -1) { os.write(buffer, 0, len); } os.flush(); } result = true; } catch (IOException e) { result = false; } finally { Util.close(os, inputStream); } return result; } 4.EditText默认不获取焦点,不自动弹出键盘 该问题出现在targetSdkVersion >=Build.VERSION_CODES.P 情况下,且设备版本为Android P以上版本,目前我们没有从源码中查到相关判断改动,解决方法在onCreate中加入如下代码: mEditText.post(() -> { mEditText.requestFocus(); mEditText.setFocusable(true); mEditText.setFocusableInTouchMode(true); }); 5.Only fullscreen activities can request orientation 异常 该问题出现在targetSdkVersion >=Build.VERSION_CODES.O_MR1 ,也就是 API 27,当设备为Android 26时(27以上已经修复,也许google觉得不妥当,又改回来了),如果非全面屏透明activity固定了方向,则出现该异常,但是当我们在小米、魅族等Android 26机型测试的时候,并没有该异常,华为机型则报该异常,这是何等的卧槽。。。没办法,去掉透明style或者去掉固定方向代码即可,其它无解 6.安装APK Intent及其它文件相关Intent /* * 自Android N开始,是通过FileProvider共享相关文件,但是Android Q对公有目录 File API进行了限制 * 从代码上看,又变得和以前低版本一样了,只是必须加上权限代码Intent.FLAG_GRANT_READ_URI_PERMISSION */ private void installApk() { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ //适配Android Q,注意mFilePath是通过ContentResolver得到的,上述有相关代码 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse(mFilePath) ,"application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); return ; } File file = new File(saveFileName + "osc.apk"); if (!file.exists()) return; Intent intent = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "net.oschina.app.provider", file); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } startActivity(intent); } 我们APK开发实践中暂时遇到的坑就这些,当然Android Q的改动是相当大的,例如还有App私有沙箱文件、定位权限和后台弹出Activity限制,这些都必须根据自身实践去踩坑适配,有条件的尽可能去阅读官方文档,参考改进。

优秀的个人博客,低调大师

[雪峰磁针石博客]python库介绍-telnetlib:Telnet客户端

python测试开发项目实战-目录 python工具书籍下载-持续更新 python 3.7极速入门教程 - 目录 简介 telnetlib模块提供的Telnet类实现了Telnet协议(参见rfc854)。它为协议字符和telnet选项提供符号常量,符号常量来源于arpa/telnet.h,去掉了前缀TELOPT_。 telnet命令有: IAC, DONT, DO, WONT, WILL, SE (Subnegotiation End), NOP (No Operation), DM (Data Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT (Are You There), EC (Erase Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin)。 class telnetlib.Telnet(host=None, port=0[, timeout]) 快速入门 #!/usr/bin/env python # -*- coding: utf-8 -*- # Author Rongzhong Xu 2016-08-25 wechat: pythontesting """ Name: telnet_demo.py Tesed in python3.5 """ import telnetlib HOST = "172.17.100.18" user = "test" password = "123456" def command(con, flag, str_=""): data = con.read_until(flag.encode()) print(data.decode(errors='ignore')) con.write(str_.encode() + b"\n") return data tn = telnetlib.Telnet(HOST) command(tn, "login: ", user) if password: command(tn, "Password: ", password) command(tn, "$", "ls") command(tn, "$", " exit") command(tn, "$", "") tn.close() 执行结果: $ python3 telnet_demo.py CentOS release 6.7 (Final) Kernel 2.6.32-573.18.1.el6.x86_64 on an x86_64 login: Password: Last login: Thu Aug 25 17:20:18 from 172.17.153.6 [test@public01 ~]$ ls [test@public01 ~]$ exit logout 参考资料 python测试等IT技术支持qq群: 144081101(后期会录制视频存在该群群文件) 591302926 567351477 本文最新版本地址 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 python官方文档:https://docs.python.org/3/library/telnetlib.html effbot: http://effbot.org/librarybook/telnetlib.htm rfc854: https://tools.ietf.org/html/rfc854.html 方法 Telnet.read_until(expected[, timeout]) 读取直到遇到了给定的字符串expected或超时秒数。 当找不到匹配时,返回读取内容。连接关闭或者没有数据时触发EOFError异常。 Telnet.read_all() 读取所有数据直到EOF,阻塞直到连接关闭。 Telnet.read_some() 读取至少一个字节的数据,除非EOF。 如果没有数据则阻塞。 Telnet.read_very_eager() 非阻塞地读取。连接关闭或者没有数据时触发EOFError异常。返回b''如果没有数据, Telnet.read_eager() 读取的已有数据。(快) 连接关闭或者没有数据时触发EOFError异常。返回b''如果没有数据, Telnet.read_lazy() 读取的已有数据(懒) 连接关闭或者没有数据时触发EOFError异常。返回b''如果没有数据, Telnet.read_very_lazy() 读取的已有数据(很懒) 连接关闭或者没有数据时触发EOFError异常。返回b''如果没有数据, Telnet.read_sb_data() 返回的SB/SE pair (suboption begin/end)之间的数据。此方法永远不会阻塞。 Telnet.open(host[, port[, timeout]]) 连接到主机。可选的第二个参数是默认为标准的 Telnet 端口 (23) 的端口号。可选的超时参数指定以秒计) 阻塞操作 (如连接尝试超时 (如果不指定,将使用全局默认超时设置)。 Telnet.msg(msg[, *args]) 当调试级别为> 0 打印调试消息。 Telnet.set_debuglevel(debuglevel) 设置调试级别。debuglevel越高信息越多。 Telnet.close() 关闭该连接。 Telnet.get_socket() 返回套接字供内部使用。 Telnet.fileno() 返回套接字对象内部使用的文件描述符。 Telnet.write(buffer) 写入字符串到套接字,加倍 IAC 的任何字符。连接关闭是可能触发OSError异常。 Telnet.interact() 交由用户控制。 Telnet.mt_interact() 多线程的版本的interact()。 Telnet.expect(list[, timeout]) 读取直到匹配正则表达式项列表中的一个。 list是一个正则表达式列表,包含编译(regex 对象)或未编译(字节字符串)。timeout以秒为单位, 默认值为无限期阻塞。 返回元组的三个项目: index为匹配正则表达式的位置;match 对象;此时读了的字节。 文件结尾或没有数据时触发EOFError异常,不匹配时返回(-1, None, data)。 如果正则表达式是贪婪模式或者如果多个表达式可以匹配相同的输入,结果是不确定的,可能取决于I/O定时。 Telnet.set_option_negotiation_callback(callback) 每次从输入流读取telnet选项时,调用callback(telnet socket, command (DO/DONT/WILL/WONT), option),后续步骤不会执行。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册