摘要
Solon,一款简约而强大的Java开发框架,拥有过滤装置和拦截器,可限制流量、验证登录、记录日志,高效实现统计分析。
正文
Solon 的过滤装置 Filter 和二种拦截器 Handler、 Interceptor
在web开发中,过滤装置、拦截器是常常采用的作用。它能够 帮大家限定总流量、认证是不是登录、纪录日志及其统计分析实行高效率这些。
今日关键沟通交流一下 Solon 架构中的过滤装置和拦截器。
Solon 是啥架构?
Solon 是一个软件式的 Java 小型开发框架。注重,抑制 简约 对外开放的标准;务求,更小、更快、更随意的感受。适用:RPC、REST API、 MVC、Micro service、WebSocket、Socket 等多种多样开发方式。
一、Solon 的过滤装置
Solon 是一个 Servelt 不相干的开发框架,因此 有自身专享的 Filter,但与 Servelt 的 Filter 作用相距并不大。此外,Solon 是一个多信号源的开发框架,因此 Filter 对 Http、Socket、WebSocket 的要求数据信号通通合理。
//插口编码
@FunctionalInterface
public interface Filter {
void doFilter(Context ctx, FilterChain chain) throws Throwable;
}
Solon Filter 是最根级的、最粗颗料度的过虑方式。它不可以挑选途径过虑,只有对全部的要求开展过虑。假如必须仅对某途径解决,必须编码内操纵,它是与 Servelt Filter 的一大差别。
一个过流保护的实例:
public class DemoApp{
public static void main(String[] args){
SolonApp app = Solon.start(DemoApp.class, args);
app.filter((ctx, chain)->{
try(AutoCloseable entry = Limiter.entry()){
chain.doFilter(ctx);
}catch (Exception e){
ctx.output("网络服务器有点儿忙,请稍后再试");
}
});
}
}
还可以用部件的方式声明:
@Component
public class BreakerFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
try(AutoCloseable entry = Limiter.entry()){
chain.doFilter(ctx);
}catch (Exception e){
ctx.output("网络服务器有点儿忙,请稍后再试");
}
}
}
Solon Filter 绝绝大部分的工作中,都能够由 Solon 拦截器 Handler 进行。
二、Solon 的拦截器
Solon 中拦截器分成二种。一是 Handler,针对要求详细地址与前后文目标的阻拦;一是 Interceptor,对 Bean 的 Method 开展阻拦。
1、Handler(Context 拦截器)
Solon 对web要求解决的实质,就是对 Context 的一路阻拦解决并最后輸出。这一路的阻拦解决可称作阻拦链,阻拦链上每一个解决连接点,即是 Context 拦截器,每一个拦截器即是 Handler 。
//插口编码
@FunctionalInterface
public interface Handler {
void handle(Context context) throws Throwable;
}
Handler 在选秀权上可分成:外置拦截器(能够 好几个)、中置拦截器(数最多一个)、后置摄像头拦截器(能够 好几个),给予了三段阻拦工作能力。在应用上又有三种方式可选,实际以下编码:
应用方式一:纯手写模式(这类方式,能够 悄悄为控制板天赋加点物品)
public class DemoApp{
public static void main(String[] args){
SolonApp app = Solon.start(DemoApp.class, args);
//中置阻拦解决
app.get("/hello",c->c.output("Hello world!"));
//外置阻拦解决(认证Token)
app.before("/hello",c->{
if(c.header("Token") == null){
//要是没有Token则中断事后解决
c.setHandled(true);
}
});
//外置阻拦解决(纪录Log)-- 阻拦链,能够 产生一种"安装"的觉得
app.before("/hello",c->{
System.out.println("纪录日志");
});
//后外置阻拦解决
app.after("/hello",c->{
System.out.println("记录时间耗费");
});
}
}
应用方式二:控制板撰写方式(这类方式较为有清晰度,自身为自己天赋加点料)
@Controller
public class DemoController {
//外置阻拦解决(认证Token)
@Mapping(value = "hello", before = true)
public void helloBef1(Context c) {
if (c.header("Token") == null) {
//要是没有Token则中断事后解决
c.setHandled(true);
}
}
//外置阻拦解决(纪录Log)
@Mapping(value = "hello", before = true)
public void helloBef2(Context c) {
System.out.println("纪录日志");
}
//中置阻拦解决
@Get
@Mapping("hello")
public String hello() {
return "Hello world!";
}
//后外置阻拦解决
@Mapping(value = "hello", after = true)
public void helloAft1(Context c) {
System.out.println("记录时间耗费");
}
}
应用方式三:注释方式(根据:@Before、@After 注释额外;这类方式较为有安装感)
//
//1. 三个阻拦解决
//
public class HelloBef1Handler implements Handler {
@Override
public void handle(Context c) throws Throwable {
if (c.header("Token") == null) {
//要是没有Token则中断事后解决
c.setHandled(true);
}
}
}
public class HelloBef1Handler implements Handler {
@Override
public void handle(Context c) throws Throwable {
if (c.header("Token") == null) {
//要是没有Token则中断事后解决
c.setHandled(true);
}
}
}
public class HelloBef2Handler implements Handler {
@Override
public void handle(Context c) throws Throwable {
System.out.println("纪录日志");
}
}
//
// 2.根据注释,额外在Action上
//
@Controller
public class DemoController {
//此引入,也可额外在控制板类上
@After({HelloAft1Handler.class})
@Before({HelloBef1Handler.class, HelloBef2Handler.class})
@Get
@Mapping("hello")
public String hello() {
return "Hello world!";
}
}
2、Interceptor(Method 拦截器)
Interceptor 阻拦的总体目标是方式 ,因此 被代理商的 Bean Method。
//插口编码
@FunctionalInterface
public interface Interceptor {
Object doIntercept(Invocation inv) throws Throwable;
}
Interceptor 一样有三种应用方式。
应用方式一:手写模式
//界定一个拦截器
public class TranInterceptor implements Interceptor {
@Override
public Object doIntercept(Invocation inv) throws Throwable{
ValHolder val0 = new ValHolder();
Tran anno = inv.method().getAnnotation(Tran.class);
TranExecutorImp.global.execute(anno, () -> {
val0.value = inv.invoke();
});
return val0.value;
}
}
//界定一个注释
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Tran {
}
//申请注册一个自然环境解决到Aop器皿
Aop.context().beanAroundAdd(Tran.class, new TranInterceptor(), 120);
//应用
@Service
public class UserService{
//根据@Tran,完成阻拦并加上事务管理适用
@Tran
public void addUser(User user){
userMapper.insert(user);
}
}
应用方式二:根据注释桥接模式(根据:@Around 注释中继一个拦截器)
//界定一个拦截器
public class TranInterceptor implements Interceptor {
@Override
public Object doIntercept(Invocation inv) throws Throwable{
ValHolder val0 = new ValHolder();
Tran anno = inv.method().getAnnotation(Tran.class);
TranExecutorImp.global.execute(anno, () -> {
val0.value = inv.invoke();
});
return val0.value;
}
}
//界定一个注释(根据@Aroud 关系一个拦截器)
@Around(value = TranInterceptor.class, index = 120))
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Tran {
}
//应用
@Service
public class UserService{
//根据@Tran,完成阻拦并加上事务管理适用
@Tran
public void addUser(User user){
userMapper.insert(user);
}
}
应用方式三:立即注释方式(根据:@Around 注释立即声明拦截器)
//界定一个拦截器
public class TranInterceptor implements Interceptor {
@Override
public Object doIntercept(Invocation inv) throws Throwable{
ValHolder val0 = new ValHolder();
Tran anno = inv.method().getAnnotation(Tran.class);
TranExecutorImp.global.execute(anno, () -> {
val0.value = inv.invoke();
});
return val0.value;
}
}
//应用
@Service
public class UserService{
@Around(value = TranInterceptor.class, index = 120))
public void addUser(User user){
userMapper.insert(user);
}
}
附:新项目详细地址
- Gitee:https://gitee.com/noear/solon
- GitHub:https://github.com/noear/solon
附:新手入门实例
- Solon 基础教程实例:https://gitee.com/noear/solon_demo
- Solon Rpc 基础教程实例:https://gitee.com/noear/solon_rpc_demo
- Solon Cloud 基础教程实例:https://gitee.com/noear/solon_cloud_demo
- Solon 升阶实例教程实例:https://gitee.com/noear/solon_advance_demo
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0