在osmp裏,osmp-http對外發布了統一的訪問接口,接受請求解析後從osmp-service容器裏獲取服務,調用並將結果返回,在這個過程當中,咱們經過編寫自定義的攔截器對請求進行攔截,主要應用如下場景 (安全、權限、數據過濾、數據格式化、記錄入參、出參日誌、調用統計分析、全鏈路日誌等AOP形爲)。java
下面咱們介紹怎樣在osmp框架下編寫咱們的第一個攔截器對非法IP的請求進行攔截。web
一、參照前面講的第一個服務的開發,搭建組件開發環境,把沒有的類和包刪除。spring
二、新增攔截器實現類OsmpDemoInterceptor.javaapache
/* * Project: 基礎組件 * FileName: SicentTestServiceImpl.java * Company: Chengdu Sicent Technology Co.,Ltd * version: V1.0 */ package com.osmp.demo.interceptor; import org.springframework.stereotype.Component; import com.osmp.intf.define.config.FrameConst; import com.osmp.intf.define.interceptor.ServiceInterceptor; import com.osmp.intf.define.interceptor.ServiceInvocation; import com.osmp.intf.define.model.ServiceContext; /** * Description:日誌攔截用於統計日誌訪問提供支撐數據 * * @author: wangkaiping * @date: 2014年9月26日 下午3:03:55 */ @Component public class OsmpDemoInterceptor implements ServiceInterceptor { @Override public Object invock(ServiceInvocation invocation) { ServiceContext context = invocation.getContext(); String ip = context.getClientInfo().get(FrameConst.CLIENT_IP); String serviceName = context.getServiceName(); System.out.println("serviceName : " + serviceName); System.out.println("IP攔截 : " + ip); if ("192.168.1.1".equals(ip)) { return "IP非法!"; } else { return invocation.process(); } } }
實現osmp-intf-define 定義的攔截器接口 ServiceInterceptor.java, 這裏咱們從ServiceInvocation裏獲取ServiceContext 上下文,並獲得客戶端信息。安全
從客戶端信息裏獲取客戶端IP 判斷 客戶端IP是否爲 "192.168.1.1" 若是是的話咱們返回IP非法,若是不是則執行請求並返回!框架
攔截器接口定義 ServiceInterceptor.javamaven
/* * Project: OSMP * FileName: ServiceInterceptor.java * version: V1.0 */ package com.osmp.intf.define.interceptor; /** * Description:攔截器 * 全部基於osmp的攔截器都須要實現該接口,攔截器按做用域分爲全局攔截器,BUNDLE攔截器,SERVICE攔截器三種類型。 * 全局攔截器(ALL): 做用於osmp的全部BUNDLE和服務。 * BUNDLE攔截器(BUNDLE): 做用於osmp指定BUNDLE下的全部服務。 * SERVICE攔截器(SERVICE): 做用於osmp指定的SERVICE服務。 * * 攔截器適用於 接口安全、權限校驗、全局日誌、調用鏈日誌Track、特定服務AOP攔截等業務場景 * * 服務發佈時,須要在service-properties 裏指定攔截器的類型(type)和匹配的攔截策略(pattern) * * <osgi:service interface="com.osmp.intf.define.interceptor.ServiceInterceptor" ref="osmp.demo.interceptor"> <osgi:service-properties> <entry key="name" value="Interceptor_demo" /> <entry key="mark" value="攔截器demo"/> <entry key="type" value="SERVICE"/> //type:ALL、BUNDLE、SERVICE <entry key="pattern" value="這裏是發佈的服務名稱"/> //支持正則匹配、 AAAService* 、 *AAA* 、 </osgi:service-properties> </osgi:service> * * 攔截器與bundle、服務兩種綁定方式: * 一、攔截器被安裝時osmp-service組件進行bundle監聽時,經過bundle獲取interface service 後解析type和 pattern並注入到ServiceContainer中。 * 二、經過osmp-web在線能夠綁定和解綁攔截器與bundle、服務。 * * @author: wangkaiping * @date: 2016年8月9日 上午9:26:32上午10:51:30 */ public interface ServiceInterceptor { Object invock(ServiceInvocation invocation); }
ServiceInvocation定義了 ServiceContext getContext(); Object process(); 兩個接口,ide
getContext()接口獲取服務上下文,上下文包含了 請求客戶端基本信息、請求參數、服務名稱、及請求的url字符串等信息ui
process()請求執行接口,默認實現爲,先從攔截器鏈裏獲取此服務對應的攔截器,若是攔截器鏈爲空則直接執行BaseDataService的execture() 調用服務,若是不爲空則執行調用攔截器鏈執行。this
默認爲 Invocation 實現 DefaultServiceInvocation.java
/* * Project: OSMP * FileName: DefaultServiceInvocation.java * version: V1.0 */ package com.osmp.http.tool; import java.util.List; import com.osmp.intf.define.interceptor.ServiceInterceptor; import com.osmp.intf.define.interceptor.ServiceInvocation; import com.osmp.intf.define.model.ServiceContext; import com.osmp.intf.define.service.BaseDataService; /** * 服務攔截器調用 * @author heyu * */ public class DefaultServiceInvocation implements ServiceInvocation { private int currentInterceptorIndex = 0; private List<ServiceInterceptor> interceptorChain; private BaseDataService dataService; private ServiceContext context; private boolean isError = true; @Override public Object process() { if(interceptorChain == null || interceptorChain.isEmpty()){ isError = false; return dataService.execute(context.getParameter()); } if(currentInterceptorIndex == interceptorChain.size()){ isError =false; return dataService.execute(context.getParameter()); } ++currentInterceptorIndex; return interceptorChain.get(currentInterceptorIndex-1).invock(this); } public DefaultServiceInvocation(List<ServiceInterceptor> interceptorChain, BaseDataService dataService, ServiceContext context) { super(); this.interceptorChain = interceptorChain; this.dataService = dataService; this.context = context; } @Override public ServiceContext getContext() { return context; } public boolean isError() { return isError; } }
三、編寫spirng配置文件 /src/main/resources/META-INF/spring/spirng-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd"> <context:component-scan base-package="com.osmp.demo.interceptor"></context:component-scan> <bean id="osmp.demo.interceptor" class="com.osmp.demo.interceptor.OsmpDemoInterceptor" /> <osgi:service interface="com.osmp.intf.define.interceptor.ServiceInterceptor" ref="osmp.demo.interceptor"> <osgi:service-properties> <entry key="name" value="Interceptor_demo" /> <entry key="mark" value="攔截器demo"/> <entry key="type" value="ALL"/> <entry key="pattern" value=""/> </osgi:service-properties> </osgi:service> </beans>
四、pom.xml 配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.osmp.baseweb</groupId> <artifactId>osmp-parent</artifactId> <version>1.0.0</version> </parent> <artifactId>osmp-interceptor-demo</artifactId> <packaging>bundle</packaging> <name>osmp-interceptor-demo</name> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Export-Package></Export-Package> <Import-Package> *;resolution:=optional </Import-Package> </instructions> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.osmp.baseweb</groupId> <artifactId>osmp-intf-define</artifactId> <version>${osmp.version}</version> </dependency> </dependencies> </project>
五、打包部署 mvn install ,將打好的bundle包(osmp-interceptor-demo-1.0.0.jar)部署到servicemix裏
六、將攔截器綁定,自動綁定、手動綁定兩種方式:
七、訪問請求
攔截器已經 生效,咱們再停掉攔截器
再次訪問
正常返回請求
至此基於osmp的攔截器開發已經完成。