2021黑五 杜甫收获

SYS独服 24.99欧元 标准配置 SYS-2-SAT-32 Server - Intel Xeon D1540 - 32GB DDR3 ECC 2133MHz - 4x 2To HDD Soft RAID 250Mbps 开机结果 cpu升级为 Intel Xeon D1541 硬盘升级为 4x4T 开了3台结果如下: 1 2 3 12-01 21:23 GRA2 d1541 4x4T 250m 硬盘均 120小时 12-02 13:02 GRA1 d1541 4x4T G口 3个硬盘6k小时,1个110小时 12-02 13:30 GRA1 d1541 4x4T 250m 3个新盘,1个1k小时 准高配:D-1540+16T硬盘+250Mbps网络 高配:D-1541CPU+16T硬盘+250Mbps网络 顶配:D-1541CPU+16T硬盘+1Gbps网络 KS独服 14.99欧元 标准配置 1 KS-LE Server - Intel Xeon E5-1620v2 - 32GB DDR3 ECC 1133MHz - 2x 2To HDD Soft RAID 100Mbps 开机结果 机器1 ...

2021年12月2日 · 1 分钟 · 浅忆

gson java.lang.NumberFormatException: empty String

问题: 反序列化时实体类型为 int/Integer/Long 等等,而json字段为string,如下 1 2 3 4 5 6 #json {"a":""} #伪代码 class test { private Integer a; } 解决方法: 为gson注册一个适配器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; public class IntTypeAdapter extends TypeAdapter<Integer> { @Override public void write(JsonWriter out, Integer value) throws IOException { out.value(value); } @Override public Integer read(JsonReader in) throws IOException { JsonToken peek = in.peek(); if (peek == JsonToken.NULL) { in.nextNull(); return null; } try { String result = in.nextString(); if ("".equals(result)) { return null; } return Integer.parseInt(result); } catch (NumberFormatException e) { throw new JsonSyntaxException(e); } } } 1 2 3 4 private Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(Integer.class, new IntTypeAdapter()) //.registerTypeHierarchyAdapter(Long.class, new LongTypeAdapter()) .create(); 需要注意的是, registerTypeHierarchyAdapter 里的类型一定要准确,一开始百度出来的是用 Number,会无法进入适配器,比如 https://www.jianshu.com/p/081ab69cf9a8 ,注册的是 int和integer,但TypeAdapter 是number。 ...

2021年9月2日 · 1 分钟 · 浅忆

javax.mail.FolderClosedException 异常

在测试 javax.mail 中的 imap 协议 idle 时会有olderClosedException异常。 背景 在Messaging对象上调用方法并且拥有该对象的Folder由于某种原因而死亡时,将引发此异常。 由于我没注意看文档,IMAPFolder.idle();是阻塞的而又没有循环读,导致直接关闭了资源~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 收件箱中共633封邮件! 收件箱中共78封未读邮件! 收件箱中共0封新邮件! 收件箱中共0封已删除邮件! ------------------------开始解析邮件---------------------------------- 支持idle Got 1 new messages --------------------------------------------------- -----关闭资源----- 标题: Re:测试邮件推送 javax.mail.FolderClosedException at com.sun.mail.imap.IMAPMessage.getProtocol(IMAPMessage.java:169) at com.sun.mail.imap.IMAPMessage.loadBODYSTRUCTURE(IMAPMessage.java:1546) at com.sun.mail.imap.IMAPMessage.getDataHandler(IMAPMessage.java:808) at javax.mail.internet.MimeMessage.getContent(MimeMessage.java:1508) at io.qyi.qqBotManage.mail.mail$1.messagesAdded(mail.java:88) at javax.mail.event.MessageCountEvent.dispatch(MessageCountEvent.java:154) at javax.mail.EventQueue.run(EventQueue.java:170) at java.lang.Thread.run(Thread.java:745) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 import com.sun.mail.imap.IMAPFolder; import javax.mail.*; import javax.mail.event.MessageCountAdapter; import javax.mail.event.MessageCountEvent; import java.io.IOException; import java.util.Properties; /** * @author LuoYe * @version 1.0 * @description: TODO * @date 2021/5/12 3:13 */ public class mail { public static void main(String[] args) throws MessagingException, IOException { init(); } public static void init() throws MessagingException, IOException { Properties props = new Properties(); props.setProperty("mail.store.protocol", "imap"); props.setProperty("mail.imap.host", "outlook.office365.com"); props.setProperty("mail.imap.port", "993"); /*tls与https需要增加以下代码*/ props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.imap.socketFactory.fallback", "false"); props.setProperty("mail.imap.socketFactory.port", "993"); Session session = Session.getInstance(props); // 创建IMAP协议的Store对象 Store store = session.getStore("imap"); // 连接邮件服务器 store.connect("账户", "密码"); // 获得收件箱 Folder folder = store.getFolder("INBOX"); // 以读写模式打开收件箱 folder.open(Folder.READ_WRITE); // 获得收件箱的邮件列表 Message[] messages = folder.getMessages(); // 打印不同状态的邮件数量 System.out.println("收件箱中共" + messages.length + "封邮件!"); System.out.println("收件箱中共" + folder.getUnreadMessageCount() + "封未读邮件!"); System.out.println("收件箱中共" + folder.getNewMessageCount() + "封新邮件!"); System.out.println("收件箱中共" + folder.getDeletedMessageCount() + "封已删除邮件!"); System.out.println("------------------------开始解析邮件----------------------------------"); // 解析邮件 /*for (Message message : messages) { IMAPMessage msg = (IMAPMessage) message; String subject = MimeUtility.decodeText(msg.getSubject()); System.out.println("[" + subject + "]未读,是否需要阅读此邮件(y/n)?"); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String answer = reader.readLine(); if ("y".equalsIgnoreCase(answer)) { System.out.println(msg.getContent().toString()); // POP3ReceiveMailTest.parseMessage(msg); // 解析邮件 // 第二个参数如果设置为true,则将修改反馈给服务器。false则不反馈给服务器 // msg.setFlag(Flag.SEEN, true); //设置已读标志 } }*/ folder.addMessageCountListener(new MessageCountAdapter() { @Override public void messagesAdded(MessageCountEvent e) { // super.messagesAdded(e); Message[] msgs = e.getMessages(); System.out.println("Got " + msgs.length + " new messages"); for (Message msg : msgs) { System.out.println("---------------------------------------------------"); try { System.out.println("标题: " + msg.getSubject()); System.out.println("内容: " + msg.getContent().toString()); } catch (MessagingException messagingException) { messagingException.printStackTrace(); } catch (IOException ioException) { ioException.printStackTrace(); } } } @Override public void messagesRemoved(MessageCountEvent e) { super.messagesRemoved(e); } }); if (folder instanceof IMAPFolder) { System.out.println("支持idle"); IMAPFolder f = (IMAPFolder) folder; f.idle(); } System.out.println("-----关闭资源-----"); // 关闭资源 folder.close(false); store.close(); } }

2021年5月12日 · 2 分钟 · 浅忆

pfSense HTTP_REFERER 登录校验问题

1 An HTTP_REFERER was detected other than what is defined in System -> Advanced (http://x.x.x.x/services_dhcp.php). If not needed, this check can be disabled in System -> Advanced -> Admin 问题: 由于服务器有多个ip,所以我就想装一个软路由来统一控制,刚装上pfSense 就无法在web登录,google搜索了半天才搜到,还是错的…… 解决办法: 1、vnc进入 PHP shell + pfSense tools 2、执行 playback disableref erercheck 注意: 一开始我搜索到的解决办法是由pfSsh.php执行,也就是 1 pfSsh.php playback disablereferercheck 但是在新版(2.5.0)执行无任何效果,低于这个版本的可以尝试这条命令。

2021年4月10日 · 1 分钟 · 浅忆

小米内测自动答题脚本

为啥要搞这个脚本呢,是真的被恶心到了,我记得我还是从高二开始就用的小米,MIUI从以前的真香,变成BUG一堆、负优化的UI。买了个小米11,到手3个月真心被这系统恶心到了,越更新越辣鸡,什么哈曼音效砍了(MIUI 12.0.22),4600ma的电池用着和老手机没什么区别,1月份首发到手,结果现在4月初所谓的MIUI12.5还没出来,以前可以随便刷开发版,现在也要个申请,关键是tmd不让过,无法了…… 这个脚本本来是打算为了答题申请内测,现在搞完反而没想法了,等用坏了以后就不用小米手机。 本脚本仅交流使用,不提供任何技术支持。 效果如下: 脚本运行环境是auto.js免费版4.0,看了半个小时直接开始撸了,附带采集功能,题库中没有的题目自动入库,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 toast("开始运行!"); // click("再次答题"); // click("同意协议并开始答题"); var myAPP = {}; // 唯一的全局变量myAPP myAPP.packageName = "com.xiaomi.vipaccount"; console.log('查找题目'); var patt = /,,.*(?=多选题|单选题)/g; for (let i = 0; i < 40; i++) { let title = textContains("选题").findOne().text(); console.log('?????????') var reg=new RegExp(patt); var result = reg.exec(title); // console.log('题目',title); title = result[0].replace(',,','').replace(' ',''); console.log(result[0]); // break; if (title == undefined) { continue; } console.log("题目:", title); // console.log(title.textMatches(patt)); let an; try { an = textContains("未选中").find(); } catch (error) { console.log('异常'); } /*增加题目到题库*/ let post = {}; post.question = title; for (let i = 0; i < an.length; i++) { let an_t = an[i].text().replace(',未选中', ''); if (i === 0) { post.answer_a = an_t; } else if (i === 1) { post.answer_b = an_t; } else if (i === 2) { post.answer_c = an_t; } else if (i === 3) { post.answer_d = an_t; } } // console.log(JSON.stringify(post)); let url = "http://192.168.15.227:8012/add_question"; let url_select = "http://192.168.15.227:8012/getQuestion?title=" + title; var r = http.get(url_select); var data_j = JSON.parse(r.body.string()); console.log('返回结果:', data_j); if(data_j.code === -1){ // 没有题库,直接提交到数据库 http.postJson(url, post); console.log(post); click(post.answer_a + ",未选中"); sleep(1000); click("下一题"); }else{ // data_j. var nc = Number(data_j.data.answer); console.log('答案',nc); if ((nc & 16) === 16) { console.log('点击',data_j.data.answer_a + ',未选中'); click(data_j.data.answer_a); } if ((nc & 32) === 32) { console.log('点击',data_j.data.answer_b + ',未选中'); click(data_j.data.answer_b); } if ((nc & 64) === 64) { console.log('点击',data_j.data.answer_c +',未选中'); click(data_j.data.answer_c); } if ((nc & 128) === 128) { console.log('点击',data_j.data.answer_d + ',未选中'); click(data_j.data.answer_d); } sleep(1000); click("下一题"); } } 不知道为啥,正则那里用了前置断言就报错…… ...

2021年4月1日 · 7 分钟 · 浅忆

H2 数据库配置DATABASE_TO_UPPER区分大小写无效

背景 刚接触这个h2内存数据库,被这个问题折腾2天了,我使用的是mybatis-plus,而H2默认 表名、列名都是大写,和mybatis plus默认的策略有冲突(SQL大写变小写加下划线),虽然可以配置关闭掉,但全部大写还是看着不习惯…… 所以百度搜了下关闭的方法,在url链接上加上 DATABASE_TO_UPPER=FALSE 就行了,但这问题就来了,由于我加了 AUTO_SERVER=TRUE 也就是混合模式,在idea中修改数据就会 报错: 1 2 3 4 5 [90079][90079] org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "information_schema" not found; SQL statement: select catalog_name from information_schema.catalogs [90079-200]. Schema "information_schema" not found; SQL statement: select catalog_name from information_schema.catalogs [90079-200] (458 ms) 解决办法 后面搜索到 github同样有人遇到了这个问题,给出的解决方法是使用 DATABASE_TO_LOWER=TRUE 参数。记得删除原来的库重新生成 。 我的配置如下: 1 2 3 4 spring.datasource.url=jdbc:h2:./db/qq_bot;DATABASE_TO_LOWER=TRUE;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9092;USER=sa;PASSWORD=sa; #spring.datasource.h2.username=admin #spring.datasource.h2.password=admin spring.datasource.h2.driver-class-name=org.h2.Driver 至于我为啥把用户名密码配置在url里…….那就是另外个问题了,哈哈哈 使用H2需要注意的问题 1、如果修改了url配置,原来的数据库要删除重新生成,因为在第一次创建数据库的时候就写死了,无法修改。 2、关于混合模式,我一直以为配置了,AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9092; 就可以使用tcp直接连接进行修改了,虽然端口开放了但会说密码错误 ,其实只是可以使用相同的url再次连接而已。 参考文章: https://github.com/h2database/h2database/issues/485

2021年3月27日 · 1 分钟 · 浅忆

关于TDengine使用上一些注意事项(坑) - 未完

第一次使用时序数据库,本来想用influxdb,搜了下说是国产的TDengine 性能更好,sql和原生差不多,所以就想尝试下,但学到现在一路的坑啊…… 这里我使用的是TDengine Docker版,安装命令 1 docker run -d -v /etc/taos:/etc/taos -p 6030:6030 -p 6035:6035 -p 6041:6041 -p 6030-6040:6030-6040/udp tdengine/tdengine:2.0.0.0 注意版本号,默认账户密码为:root/taosdata 常见问题 1、 java.sql.SQLException: TDengine Error: Invalid timestamp 如果本地时区要和服务端一样 解答:https://github.com/taosdata/TDengine/issues/4345# 2、本地驱动版本、maven TDengine 版本、服务端版本 要一致 3、本地开发需要设置TDengine驱动环境变量 1 -Djava.library.path=C:\TDengine\driver 4、TDengine Error: Unable to resolve FQDN 这个居然还要保持主机名一致…….也就是要设置host ,docker版服务端也要在docker里设置,但官网提供的docker创建命令并未配置环境变量。

2021年3月11日 · 1 分钟 · 浅忆

RabbitMQ Java Client 并发问题思考(一)

此篇文章仅作为个人笔记,由于初学难免有理解错误的地方,请大佬指正~ 由于我这个部分没有使用SpringBoot,使用的是RabbitMq java Client API 所以在Springboot上的有些功能用不了,只能手动实现,故在思维上走了一个坑。 测试代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public static void main(String[] args) { //连接工厂 ConnectionFactory factory = new ConnectionFactory(); // factory.useNio(); // factory.setNioParams(new NioParams().setNbIoThreads(4)); factory.setHost("xxx.xxx.xxx.xxx"); factory.setPort(port); factory.setUsername("username"); factory.setPassword("password"); factory.setVirtualHost("msgpush"); // f.setConnectionTimeout(5000); // f.setHandshakeTimeout(3000); ExecutorService service = Executors.newFixedThreadPool(30); factory.setSharedExecutor(service); // 设置自动恢复 factory.setAutomaticRecoveryEnabled(true); factory.setNetworkRecoveryInterval(2); factory.setTopologyRecoveryEnabled(true);// 设置不重新声明交换器,队列等信息。 System.out.println("检索请求的最大频道数:" + factory.getRequestedChannelMax()); // f.setRequestedChannelMax(10); try { // Channel channel = f.newConnection().createChannel(); //建立连接 Connection c = factory.newConnection("push Client"); c.addShutdownListener(new ShutdownListener() { @Override public void shutdownCompleted(ShutdownSignalException e) { System.out.println( "断线了......"); } }); //建立信道 Channel ch = c.createChannel(); //声明队列,如果该队列已经创建过,则不会重复创建 //ch.queueDeclare("QueueWX", false, false, false, null); System.out.println("等待接收数据"); // 单条消息的大小限制,一般设为0或不设置,不限制大小 int prefecthSize = 0; // 告诉RabbitMQ不要同时给消费端推送n条消息,一旦有n个消息还没ack,则该consumer将block掉,直到有ack;注意在自动应答下不生效 int prefecthCount = 5; // 表示是否应用于channel上,即是channel级别还是consumer级别 boolean global = true; ch.basicQos(3); //消费者取消时的回调对象1 CancelCallback cancelHandel = new CancelCallback() { @Override public void handle(String consumerTag) throws IOException { System.out.println(consumerTag + " 链接已断开"); } }; /*微信*/ DeliverImpl deliverWx = new DeliverImpl(ch, MQEnum.QUEUE_WX); ch.basicConsume(MQEnum.QUEUE_WX.getData(), false, deliverWx, cancelHandel); /*企业微信*/ DeliverImpl deliver = new DeliverImpl(ch, MQEnum.QUEUE_WORKWX); //第二个参数为消息回执,消息确认处理完成,为true为自动确认,只要消息发送到消费者即消息处理成功;为false为,手动发送确认回执,服务器才认为这个消息处理成功 ch.basicConsume(MQEnum.QUEUE_WORKWX.getData(), false, deliver, cancelHandel); /*钉钉*/ DeliverImpl deliverDing = new DeliverImpl(ch, MQEnum.QUEUE_DINGDING); ch.basicConsume(MQEnum.QUEUE_DINGDING.getData(), false, deliverDing, cancelHandel); /*tg*/ DeliverImpl deliverTg = new DeliverImpl(ch, MQEnum.QUEUE_TG); ch.basicConsume(MQEnum.QUEUE_TG.getData(), false, deliverTg, cancelHandel); } catch (IOException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } } ...

2021年3月9日 · 4 分钟 · 浅忆

国内WordPress启用谷歌验证码(noCaptcha )

众所周知,noCaptcha 的验证接口和css是被屏蔽的,所以可以使用 recaptcha.net 这个google在国内的域名。想着有轮子绝不撸代码的想法,试了几款插件,找到一款对代码修改最小的插件(或者直接不用修改,我目前使用的这款主题需要手动修改)。 1、安装插件 https://cn.wordpress.org/plugins/advanced-nocaptcha-recaptcha/ 2、启用并设置插件 注册 recaptcha 秘钥。https://www.google.com/recaptcha/admin/ 3、修改主题代码(可选) 同理,如果评论的时候没有进行验证,提交没有显示错误信息,那么只需要对提交评论的 g-recaptcha-response 字段就行判断一下就可以了。 每款主题的输错错误方式不一样,所以自己修改~ 同时还需要添加验证代码 1 2 anr_verify_captcha() 成功时返回值为true,否则为false。

2021年3月1日 · 1 分钟 · 浅忆

Spring Boot 通过SMTP发送电子邮件(ssl/tls)

使用的技术: Spring Boot 2.3.2 Java Mail 1.6.2 Maven 3 Java 8 1、添加依赖 1 spring-boot-starter-mail 1 2 3 4 5 <!-- send email --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 2、配置 application.properties 这里得注意下了,除了邮件服务商说明同时支持tls或者ssl,否则需要将tls/ssl分开配置 ,这里我使用得是outlook,所以只支持 tls 587端口,一开始我配置成ssl,走了一个坑。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=username spring.mail.password=password # Other properties spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.connectiontimeout=5000 spring.mail.properties.mail.smtp.timeout=5000 spring.mail.properties.mail.smtp.writetimeout=5000 # 这里是tls的配置项,如果没有使用587,则要注释掉 # TLS , port 587 spring.mail.properties.mail.smtp.starttls.enable=true # 这里是ssl的配置项,如果没有使用465,则要注释掉 # SSL, post 465 #spring.mail.properties.mail.smtp.socketFactory.port = 465 #spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory 1 2 3 4 5 6 7 8 如果是这个错误,那么就是你把tls/ssl的配置弄反了。 nested exception is: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: smtp.office365.com, port: 587; nested exception is: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?; message exceptions (1) are: Failed message 1: javax.mail.MessagingException: Could not connect to SMTP host: smtp.office365.com, port: 587; nested exception is: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?] with root cause 3、发送文本邮件 1 2 3 4 5 6 7 8 9 10 11 import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; @Autowired private JavaMailSender javaMailSender; void sendEmail() { SimpleMailMessage msg = new SimpleMailMessage(); msg.setTo("to_1@gmail.com", "to_2@gmail.com", "to_3@yahoo.com"); msg.setSubject("Testing from Spring Boot"); msg.setText("Hello World \n Spring Boot Email"); javaMailSender.send(msg); } 4、发送html格式的邮件 1 2 3 4 5 6 7 8 9 10 @GetMapping("sendMail") void sendMain() throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true); message.setFrom("浅忆博客(系统)<server@curlc.com>"); message.setTo("xxxxx@qq.com"); message.setSubject("HTML邮件"); message.setText("<h1>Check attachment for image!</h1>", true); mailSender.send(mimeMessage); } 5、发送HTML电子邮件和文件附件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import org.springframework.core.io.ClassPathResource; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; void sendEmailWithAttachment() throws MessagingException, IOException { MimeMessage msg = javaMailSender.createMimeMessage(); // true = multipart message MimeMessageHelper helper = new MimeMessageHelper(msg, true); helper.setTo("to_@email"); helper.setSubject("Testing from Spring Boot"); // default = text/plain //helper.setText("Check attachment for image!"); // true = text/html helper.setText("<h1>Check attachment for image!</h1>", true); // hard coded a file path //FileSystemResource file = new FileSystemResource(new File("path/android.png")); helper.addAttachment("my_photo.png", new ClassPathResource("android.png")); javaMailSender.send(msg); } ...

2021年2月17日 · 2 分钟 · 浅忆