Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权等一系列权限相关问题。Sa-Token 的 API 设计非常简单,有多简单呢?以登录认证为例,你只需要:
// 在登录时写入当前会话的账号id
StpUtil.login(10001);
// 然后在需要校验登录处调用以下方法:
// 如果当前会话未登录,这句代码会抛出 `NotLoginException` 异常
StpUtil.checkLogin();
没错,在 Sa-Token 中,登录认证就是如此简单,不需要任何的复杂前置工作,只需这一行简单的API调用,就可以完成会话登录认证!
当你受够 Shiro、SpringSecurity 等框架的三拜九叩之后,你就会明白,相对于这些传统老牌框架,Sa-Token 的 API 设计是多么的简单、优雅!
权限认证示例(只有具备 user:add 权限的会话才可以进入请求
@SaCheckPermission("user:add")
@RequestMapping("/user/insert")
public String insert(SysUser user) {
// ...
return "用户增加";
}
// 使账号id为 10001 的会话强制注销登录
StpUtil.logoutByLoginId(10001);
在 Sa-Token 中,绝大多数功能都可以 一行代码 完成:
StpUtil.login(10001); // 标记当前会话登录的账号id
StpUtil.getLoginId(); // 获取当前会话登录的账号id
StpUtil.isLogin(); // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout(); // 当前会话注销登录
StpUtil.logoutByLoginId(10001); // 让账号为10001的会话注销登录(踢人下线)
StpUtil.hasRole("super-admin"); // 查询当前账号是否含有指定角色标识, 返回true或false
StpUtil.hasPermission("user:add"); // 查询当前账号是否含有指定权限, 返回true或false
StpUtil.getSession(); // 获取当前账号id的Session
StpUtil.getSessionByLoginId(10001); // 获取账号id为10001的Session
StpUtil.getTokenValueByLoginId(10001); // 获取账号id为10001的token令牌值
StpUtil.login(10001, "PC"); // 指定设备标识登录,常用于“同端互斥登录”
StpUtil.logoutByLoginId(10001, "PC"); // 指定设备标识进行强制注销 (不同端不受影响)
StpUtil.openSafe(120); // 在当前会话开启二级认证,有效期为120秒
StpUtil.checkSafe(); // 校验当前会话是否处于二级认证有效期内,校验失败会抛出异常
StpUtil.switchTo(10044); // 将当前会话身份临时切换为其它账号
一款极大程度解放你的 HTTP 接入工作的强大 HTTP 客户端框架。HTTP 协议很复杂吗?那是因为你还没有使用过 Forest,虽然业内有很多其他优秀的HTTP 客户端,但是你错过了 Forest,将会错过一大片优雅美丽的森林。
它能够将 HTTP 的请求参数绑定到 Java 接口上,之后调用 Java 接口就等于在发送 HTTP 请求。一切面向于接口。
很多公司需要在 Java 后台调用许多第三方 HTTP 接口,比如微信支付、友盟等等第三方平台。
公司内部还有很多服务是用世界最好语言写的,接口自然也只能通过 HTTP 接口来调用。于是日积月累下来,在 Java 代码中就有许许多多各式各样的 HTTP 调用接口,而且调用方式也不统一,有 HttpClient 写的、有 OkHttp 写的、有自己包装的,光公司内部不同人包装的 HTTP 工具类就有两三种。
而且 url 基本写死在代码中,很难维护,不同接口又有不同的参数传输方式,有 GET 、有 POST,有 JSON 传输的、有 XML 传输的。当有一个接口需要修改,完了,光找到代码在什么地方就要花半天时间。
/**
* 高德地图服务客户端接口
*/
@BaseRequest(baseURL = "http://ditu.amap.com")
public interface Amap {
/**
* 根据经纬度获取详细地址
* @param longitude 经度
* @param latitude 纬度
* @return 详细地址信息
*/
@Get("/service/regeo")
Map getLocation(@Query("longitude") String longitude, @Query("latitude") String latitude);
}
......
Amap amap = Forest.client(Amap.class);
// 发送请求查询经纬度
Map locationInfo = amap.getLocation("32.1242832", "56.3290434");
其实,我们处理 HTTP 的工作时,除了浪费在组装各种请求参数外,大部分时间都花了在序列化和反序列化各种格式的数据上,如 JSON 和 XML。
以前用 HttpClient,这些重复的机械性工作都要自己来搞,很是麻烦。
// 直接将 MyUserInfo 转换成 JSON
// 将服务端响应返回的 JSON 数据转换成 Result<Boolean> 类对象
@Post("http://localhost:8080/user")
Result<Booelean> createUser(@JSONBody MyUserInfo user);
之前也用过这两款开源框架,都很强大,但各有优缺点。
Retrofit 的主要的问题时和 OkHttp 绑的太死,有些功能被 OkHttp 限制住了,比如我想处理 Get 请求传输 Body 数据这种非标准的 HTTP 请求就很难办到,而 Forest 可以随意切换 OkHttp 和 HttpClient 作为后端,需要用哪个时用哪个。
3. LiteFlow
你需要这么像这样去定义你的组件:
//这里普通组件
@LiteflowComponent(id = "a", name = "组件A描述")
public class ACmp extends NodeComponent {
@Override
public void process() {
//do your business
}
}
//这是条件组件
@LiteflowComponent(id = "b", name = "组件B描述")
public class BCondCmp extends NodeCondComponent {
@Override
public String processCond() {
//do your business
return "e";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b(c|d|e)"/> <!-- c为路由组件,用来路由到c,d,e -->
<then value="sub_chain"/> <!-- 子流程 -->
</chain>
<chain name="sub_chain">
<when value="f,g,h"/> <!-- when代表并行 -->
<then value="j,k" /> <!-- then代表串行 -->
</chain>
</flow>
这样你的系统就会按照规则文件定义的方式,去执行你的业务组件。是不是很简单?
LiteFlow 为每一个请求都去开辟申请了一个 Slot,你可以理解为上下文,所有的组件共享这个 Slot。你可以在任意组件里通过对 Slot 的访问来获得任意数据,也可以存放任意数据。你也可以扩展 Slot,自定义这个 Slot 的属性。
@LiteflowComponent(id = "a", name = "组件A描述")
public class ACmp extends NodeComponent {
@Override
public void process() {
Slot slot = this.getSlot();
//通过对slot的getData,setData,或者存取你自己扩展的slot属性
}
}
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="普通脚本" type="script">
<![CDATA[
def a=3;
def b=2;
slot.setData("s1",a*b);
]]>
</node>
<node id="s2" name="条件脚本" type="cond_script">
<![CDATA[
count = slot.getData("count");
if(count > 100){
return "a";
}else{
return "b";
}
]]>
</node>
</nodes>
<chain name="chain1">
<then value="a,b,c,s1"/>
</chain>
<chain name="chain2">
<then value="d,s2(a|b)"/>
</chain>
</flow>
有了脚本语言的支持,连业务代码是不是都可以热部署了?香不香?
4. JPom
一款简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件。中小公司团队 DevOps 的福音!轻量且强大,你不试试?