用 javax.mail 发送邮件

工作中遇到了用 Java 通过 SMTP 发送邮件的需求,调研了一圈发现基本上用的都是 javax.mail 来实现的,这个玩意儿是上古年间 Java EE 的时候搞的一个 Java 的组件之一,API 设计得令人非常难以理解。我在使用中遇到的最大的问题是,有很多配置项你可以从很多地方设置,但是其实在真正发邮件的时候,你不知道程序会使用哪个地方配置的信息。比如说 SMTP 服务器的 Host,你可以在 Properties 里传入,也可以在 connect 的时候传入,但是没有任何的文档说明在两个地方都配置了的情况下程序会使用哪一处(其实我最终也没搞明白)。

总之,如果想要一个简单而现代化的解决方案,可以使用一个基于 javax.mail 开发的库 Simple Java Mail 。但是如果不想引入多余的依赖,那就复制我这一段例程改改用吧。

继续阅读
发表在 搬砖杂记 | 标签为 , , , | 留下评论

从源代码分析CAS的Session过期时间配置

CAS 文档的 Ticket Expiration Policies 章节中描述了 TGC 的过期策略,可是在实际配置的时候还是会遇到过期策略行为与配置不太相符的问题。本文结合源代码,对 CAS 的过期策略配置进行准确的描述,希望能够帮助到各位。

继续阅读
发表在 折腾 CAS, 搬砖杂记 | 标签为 , | 留下评论

极光快投无法连接 WiFi

不知道为什么,使用默认的蓝牙广播连接模式总是说我WiFi密码错误。只有兼容模式才能连上。但是兼容模式很难进去,所以折腾了好久才连上。

所以怎么进入兼容模式呢。只要把极光快投的APP的蓝牙权限关了,他就会提示是否进入兼容模式。希望跟我有同样问题的人不要再被这个傻逼问题坑了。

发表在 Misc | 标签为 , | 留下评论

使用正则表达式截取JSON中的key和value

前几天,一个同事提了一个正则相关的问题:在一个可能多层嵌套的 JSON 里,某些 Field 的 Value 中可能出现 “password=xxxxxxx”这样的模式,如何这个 Value 和它对应的 Field Name 匹配出来呢?

我们以这个 JSON 为例:

{
    "test1": "asdf",
    "test2": "2321312312312",
    "test_json": {
        "test": {
            "123": "one two three",
            "cookies": "asdfasdf=asdfa\"sdf\"; password=xxxxxx; 123=\"asdfasdf\""
        }
    },
    "abc": 1213
}

折腾了很久,最后用反向预查做出来了。就是长得比较难看,先摆出来:

"((?:(?:[^"])|(?:(?<=\\)"))*)":\s*"((?:(?:(?:[^"])|(?:(?<=\\)"))*)password=(?:(?:(?:[^"])|(?:(?<=\\)"))*))

现在解释一下。主要难点在于 ((?:(?:[^"])|(?:(?<=\)"))*) 这个东西。我匹配的思路是这样的:如果在 Field Name 或者 Field Value 中出现了 " 这个符号,那么它一定是以 \" 这样的形式出现的,所以这部分正则的意思是“匹配一个字符,这个字符要么是非 " 的字符((?:[^"])),要么是前面带有一个 \" 字符((?:(?<=\)"));这样的字符出现零次或者无限多次”。

(?:) 的意思是,不要捕获这个括号内的组,这样我们在从匹配结果中通过 group 编号获取数据的时候会方便一些。

其他的部分应该很好理解了,这里不再赘述。最后推荐一个超级厉害的正则表达式工具:https://regex101.com 。感兴趣的朋友可以把本文给出的测试用例和正则表达式粘贴进去试试效果。

发表在 Misc | 标签为 , , , | 留下评论

Apereo CAS 文档常用索引

CAS Protocol Specification

https://apereo.github.io/cas/5.3.x/protocol/CAS-Protocol-Specification.html

CAS 协议的详细描述,包括了各种 URL 的作用,接受的请求体以及返回结构。

CAS Protocol

https://apereo.github.io/cas/5.3.x/protocol/CAS-Protocol.html

CAS 协议的简要描述,利用时序图和一些简单的概念介绍,迅速地对 CAS 有一个初步的了解。

CAS RELEASE

https://github.com/apereo/cas/milestones

CAS 的里程碑,可以在这里查看最新的版本。

CAS Properties

https://apereo.github.io/cas/5.3.x/installation/Configuration-Properties.html

CAS>=6.0 中,已经被移动到了 https://apereo.github.io/cas/6.0.x/configuration/Configuration-Properties.html

CAS 所有的配置项集合。如果遇到了不知道是用来干什么的配置项,在这里就能查到(虽然也不一定会具体说是干什么的)。

发表在 折腾 CAS, 搬砖杂记 | 标签为 | 留下评论

Apereo CAS 调试

如何在 Intellij 里调试

其实只要 java -jar cas.war 起起来,然后加个 debug jvm agent 参数就完事了。但是毕竟自己打命令还是麻烦,所以我们这边用 intellij 来跑我们的 war 包,跑起来的时候 intellij 自己就会帮我们把参数加上,并且把 debugger attach 到这个 jmv 里,非常方便。

intellij 配置

注意这个 Before launch 区域,我们可以在跑 war 包之前加一个动作,让 intellij 跑一个 clean build 的 task,这样每次运行的包都能保证是最新的。

如何调试 war 包里的 lib

org.apereo.cas:cas-server-webapp-tomcat:war 里的 WEB-INF/lib 目录下可以看到很多 jar 包,包括 cas-server-core。这时候我们会发现在 Intellij 里双击 shift 然后输入包里的类 (比如 DefaultCentralAuthenticationService 这个类),是没法找到的。因为这个 jar 包里的 lib 的源码不在 source.jar 里。

怎么办呢?我们需要直接把它引入到项目里,就能调试了:

testCompile group: 'org.apereo.cas', name: 'cas-server-core', version: project.'cas.version'

把它放到 testCompile 里可以避免我们在 build cas.war 的时候把这个包重复引入,这样就达到了既能调试又能不引入多余依赖的效果。

发表在 折腾 CAS, 搬砖杂记 | 标签为 | 留下评论