osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)

阅读更多

在osmp里,osmp-http对外发布了统一的访问接口,接受请求解析后从osmp-service容器里获取服务,调用并将结果返回,在这个过程中,我们通过编写自定义的拦截器对请求进行拦截,主要应用以下场景 (安全、权限、数据过滤、数据格式化、记录入参、出参日志、调用统计分析、全链路日志等AOP形为)。

下面我们介绍怎样在osmp框架下编写我们的第一个拦截器对非法IP的请求进行拦截。

 

1、参照前面讲的第一个服务的开发,搭建组件开发环境,把没有的类和包删除。

2、新增拦截器实现类OsmpDemoInterceptor.java

 

/*   
 * 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.java

 

/*   
 * 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)
 * 
 * 
		
			
			
			 //type:ALL、BUNDLE、SERVICE
			  //支持正则匹配、   AAAService*  、  *AAA* 、   
		
	
 * 
 * 拦截器与bundle、服务两种绑定方式:
 * 1、拦截器被安装时osmp-service组件进行bundle监听时,通过bundle获取interface service 后解析type和 pattern并注入到ServiceContainer中。
 * 2、通过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(); 两个接口,

 

getContext()接口获取服务上下文,上下文包含了 请求客户端基本信息、请求参数、服务名称、及请求的url字符串等信息

 

process()请求执行接口,默认实现为,先从拦截器链里获取此服务对应的拦截器,如果拦截器链为空则直接执行BaseDataService的execture() 调用服务,如果不为空则执行调用拦截器链执行。

 

默认为 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 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 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;
    }
    

}

 

 

 

 

3、编写spirng配置文件 /src/main/resources/META-INF/spring/spirng-context.xml

 




	

	
	
		
			
			
			
			
		
	
	

 

 

  • 将拦截器实现发布为服务
  • 服务属性包括 name、mark、type、pattern
  • name:拦截器名称
  • mark:拦截器注释 
  • type:拦截器类型(ALL:全局拦截   BUNDLE:bundle拦截器  SERVICE:服务拦截器)可以省略,默认为ALL 全局拦截
  • pattern:拦截匹配 (只有type 不为 ALL生效,可以省略 eg: 正则匹配、   AAAService*  、  *AAA* )

4、pom.xml 配置

 


	4.0.0
	
		com.osmp.baseweb
		osmp-parent
		1.0.0
	

	osmp-interceptor-demo
	bundle
	osmp-interceptor-demo

	
		
			
				org.apache.felix
				maven-bundle-plugin
				true
				
					
						${project.artifactId}
						
						
							*;resolution:=optional
						
					
				
			
		
	

	
		
			com.osmp.baseweb
			osmp-intf-define
			${osmp.version}
		
	

 

5、打包部署 mvn install ,将打好的bundle包(osmp-interceptor-demo-1.0.0.jar)部署到servicemix里

 
osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第1张图片
 

6、将拦截器绑定,自动绑定、手动绑定两种方式:

  • 自动绑定:在将拦截器部署到servicemix的时候 osmp-service会监听拦截器接口服务,解析 typ、pattern进行自动绑定
  • 手动绑定:我们将拦截器部署后,如果没有添加type、pattern拦截器属性时,可以通过调用osmp-config提供的接口手动绑定。

 
osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第2张图片
 

 
osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第3张图片
 7、访问请求

 

 

 拦截器已经 生效,我们再停掉拦截器



 

再次访问


osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第4张图片
 

 正常返回请求

 

至此基于osmp的拦截器开发已经完成。

 

 

 

 

 

 

 

 

  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第5张图片
  • 大小: 32 KB
  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第6张图片
  • 大小: 48.7 KB
  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第7张图片
  • 大小: 12.3 KB
  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第8张图片
  • 大小: 24.7 KB
  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第9张图片
  • 大小: 5.3 KB
  • osgi实战项目(osmp)一步一步玩转osgi之拦截器(8)_第10张图片
  • 大小: 28.1 KB
  • 查看图片附件

你可能感兴趣的:(osgi,soa,微服务,servicemix,karaf)