`
lobin
  • 浏览: 425524 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring Thrift, Hessian like over Http

 
阅读更多

 

public class ThriftExporter extends RemoteExporter implements InitializingBean {

	private static final Logger LOGGER = LoggerFactory.getLogger(ThriftExporter.class);

	public static final String CONTENT_TYPE_HESSIAN = "application/x-thrift";

	protected TProcessorFactory processorFactory_;

	protected TTransportFactory inputTransportFactory_ = new TTransportFactory();
	protected TTransportFactory outputTransportFactory_ = new TTransportFactory();

	protected TProtocolFactory inputProtocolFactory_;
	protected TProtocolFactory outputProtocolFactory_;

	protected TServerEventHandler eventHandler_;

	protected Class<?> processorClass;

	@Override
	public void afterPropertiesSet() throws Exception {
		//		LocationThrfitTestService.Processor<LocationThrfitTestService.Iface> processor = new LocationThrfitTestService.Processor<LocationThrfitTestService.Iface>(new LocationThrfitTestServiceImpl());
		//		LocationThrfitTestService.Processor<LocationThrfitTestService.Iface> processor = new LocationThrfitTestService.Processor<LocationThrfitTestService.Iface>((LocationThrfitTestService.Iface) getProxyForService());

		Object service = getService();
		Class<?> serviceInterface = getServiceInterface();
		Constructor<?> constructor = processorClass.getConstructor(serviceInterface);
		TProcessor processor = (TProcessor) constructor.newInstance(getProxyForService());

		processorFactory_ = new TProcessorFactory(processor);

		TBinaryProtocol.Factory portFactory = new TBinaryProtocol.Factory(true, true);
		inputProtocolFactory_ = portFactory;
		outputProtocolFactory_ = portFactory;

		eventHandler_ = null;
	}

	public void invoke(InputStream inputStream, OutputStream outputStream) throws Throwable {
		//Assert.notNull(this.skeleton, "Thrift exporter has not been initialized");
		//doInvoke(this.skeleton, inputStream, outputStream);

		TIOStreamTransport client_ = new TIOStreamTransport(inputStream, outputStream);

		TProcessor processor = null;
		TTransport inputTransport = null;
		TTransport outputTransport = null;
		TProtocol inputProtocol = null;
		TProtocol outputProtocol = null;

		TServerEventHandler eventHandler = null;
		ServerContext connectionContext = null;

		try {
			processor = processorFactory_.getProcessor(client_);
			inputTransport = inputTransportFactory_.getTransport(client_);
			outputTransport = outputTransportFactory_.getTransport(client_);
			inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
			outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);	  

			eventHandler = getEventHandler();
			if (eventHandler != null) {
				connectionContext = eventHandler.createContext(inputProtocol, outputProtocol);
			}
			// we check stopped_ first to make sure we're not supposed to be shutting
			// down. this is necessary for graceful shutdown.
			// while (true) {
			//
			//     if (eventHandler != null) {
			//         eventHandler.processContext(connectionContext, inputTransport, outputTransport);
			//     }
			//
			//     if(stopped_ || !processor.process(inputProtocol, outputProtocol)) {
			//         break;
			//     }
			// }


			if (eventHandler != null) {
				eventHandler.processContext(connectionContext, inputTransport, outputTransport);
			}

			processor.process(inputProtocol, outputProtocol);
		} catch (TSaslTransportException ttx) {
			// Something thats not SASL was in the stream, continue silently 
		} catch (TTransportException ttx) {
			// Assume the client died and continue silently
		} catch (TException tx) {
			LOGGER.error("Thrift error occurred during processing of message.", tx);
		} catch (Exception x) {
			LOGGER.error("Error occurred during processing of message.", x);
		} finally {
			if (eventHandler != null) {
				eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
			}
			if (inputTransport != null) {
				inputTransport.close();
			}
			if (outputTransport != null) {
				outputTransport.close();
			}
			if (client_.isOpen()) {
				client_.close();
			}
		}
	}

	public TServerEventHandler getEventHandler() {
		return eventHandler_;
	}

	public void setProcessorClass(Class<?> processorClass) {
		this.processorClass = processorClass;
	}
}

 

 

 

public class ThriftServiceExporter extends ThriftExporter implements HttpRequestHandler {

	/**
	 * 
	 */
	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		if (!"POST".equals(request.getMethod())) {
			throw new HttpRequestMethodNotSupportedException(request.getMethod(),
					new String[] {"POST"}, "ThriftServiceExporter only supports POST requests");
		}

		response.setContentType(CONTENT_TYPE_HESSIAN);
		try {
		  invoke(request.getInputStream(), response.getOutputStream());
		}
		catch (Throwable ex) {
		  throw new NestedServletException("Thrift skeleton invocation failed", ex);
		}
	}

}

 

public class ThriftProxy implements InvocationHandler {
	private static final Logger log = Logger.getLogger(ThriftProxy.class.getName());
        ....

        protected Class<?> skeletonClass;

        /**
	 * Package protected constructor for factory
	 */
	ThriftProxy(ThriftProxyFactory factory, URL url)
	{
		_factory = factory;
		_url = url;
	}

	/**
	 * Protected constructor for subclassing
	 */
	protected ThriftProxy(URL url, ThriftProxyFactory factory)
	{
		_factory = factory;
		_url = url;
	}

	/**
	 * Returns the proxy's URL.
	 */
	public URL getURL()
	{
		return _url;
	}

	/**
	 * Handles the object invocation.
	 *
	 * @param proxy the proxy object to invoke
	 * @param method the method to call
	 * @param args the arguments to the proxy object
	 */
	public Object invoke(Object proxy, Method method, Object []args) throws Throwable {
		THttpClient transport = new THttpClient(_url.toString());
		TProtocol protocol = new TBinaryProtocol(transport);

		Constructor<?> constructor = skeletonClass.getConstructor(new Class<?>[] {TProtocol.class});
		proxy = constructor.newInstance(protocol);
		Method targetMethod = skeletonClass.getMethod(method.getName(), method.getParameterTypes());
		return targetMethod.invoke(proxy, args);
	}
	
	public void setSkeletonClass(Class<?> skeletonClass) {
		this.skeletonClass = skeletonClass;
	}

        ....

}

 

public class ThriftProxyFactory implements ServiceProxyFactory, ObjectFactory {

    .......
  
    protected Class<?> skeletonClass;
	
	public ThriftProxyFactory() {
		
	}
	
	public ThriftProxyFactory(Class<?> skeletonClass) {
		this.skeletonClass = skeletonClass;
	}

	@Override
	public Object create(Class api, String url) throws MalformedURLException {
		return create(api, url,
				Thread.currentThread().getContextClassLoader());
	}

	public Object create(Class api, String urlName, ClassLoader loader)
			throws MalformedURLException
	{
		if (api == null)
			throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
		ThriftProxy handler = null;

		if (false && urlName.startsWith("jms:")) {
			/*
		      String jndiName = urlName.substring("jms:".length());

		      try {
		        handler = new HessianJMSProxy(this, jndiName, _connectionFactoryName);
		      } catch (Exception e) {
		        log.info("Unable to create JMS proxy: " + e);
		        return null;
		      }
			 */
		} 
		else {
			URL url = new URL(urlName); 
			handler = new ThriftProxy(this, url);
			handler.setSkeletonClass(skeletonClass);
		}

		return Proxy.newProxyInstance(loader,
				new Class[] {api},
				handler);
	}

	public void setSkeletonClass(Class<?> skeletonClass) {
		this.skeletonClass = skeletonClass;
	}

      ....
}

 

 

namespace java com.chos.test.service

# >thrift-0.10.0.exe --gen java -out . ./com/chos/test/service/LocationThrfitTestService.thrift

struct Location {
    1: optional i32 id;
    
    # 经度
    2: optional double longitude,
    
    # 纬度
    3: optional double latitude,
    
    # 海拔高度
    4: optional double altitude
}

service LocationThrfitTestService {
    void add(Location location), 
    Location get(i32 id), 
    list<Location> getList()
}

 

 

 

@Service("locationThrfitTestService")
public class LocationThrfitTestServiceImpl implements LocationThrfitTestService.Iface {

	private Map<Integer, Location> list;
	
	public LocationThrfitTestServiceImpl() {
		list = new ConcurrentHashMap<>();
	}
	
	@Override
	public void add(Location location) throws TException {
		list.put(location.getId(), location);
	}

	@Override
	public Location get(int id) throws TException {
		return list.get(id);
	}

	@Override
	public List<Location> getList() throws TException {
		return new LinkedList<>(list.values());
	}

}

 

 

<bean name="/LocationThrfitTestService"    
        class="com.chos.test.ThriftServiceExporter">    
        <!-- service的ref与HelloServiceImpl中@Service中配置的一致 -->    
        <property name="service" ref="locationThrfitTestService" />    
        <property name="processorClass" 
            value="com.chos.test.service.LocationThrfitTestService.Processor" />
        <!-- 接口的路径 -->
        <property name="serviceInterface"    
            value="com.chos.test.service.LocationThrfitTestService.Iface" />    
    </bean>

 

    <servlet>  
    	<servlet-name>remote</servlet-name>  
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    	<load-on-startup>1</load-on-startup>  
	</servlet>  
  
	<servlet-mapping>  
    	<servlet-name>remote</servlet-name>  
    	<url-pattern>/service/*</url-pattern>  
	</servlet-mapping>

 

 

@Test
public void add() {
	try {
		String url = "http://localhost:8080/springhessiantest/service/LocationThrfitTestService";    
		
		// com.chos.test.ThriftProxyFactory instead
		ThriftProxyFactory factory = new ThriftProxyFactory(LocationThrfitTestService.Client.class);  
		LocationThrfitTestService.Iface locationThrfitTestService = (LocationThrfitTestService.Iface) factory.create(LocationThrfitTestService.Iface.class, url);    
		
		Location location = new Location();
		location.setId(3);
        location.setLongitude(5109.5);
        location.setLatitude(712920.317);
        location.setAltitude(100);
		locationThrfitTestService.add(location);    
		
		Location ret = locationThrfitTestService.get(location.getId());
		System.out.println(ret.toString());
	} catch (Exception e) {    
		e.printStackTrace();    
	}
}

@Test
public void getList() {
	try {
		String url = "http://localhost:8080/springhessiantest/service/LocationThrfitTestService";    
		
		// com.chos.test.ThriftProxyFactory instead
		ThriftProxyFactory factory = new ThriftProxyFactory(LocationThrfitTestService.Client.class);  
		LocationThrfitTestService.Iface locationThrfitTestService = (LocationThrfitTestService.Iface) factory.create(LocationThrfitTestService.Iface.class, url);    
		
        List<Location> list = locationThrfitTestService.getList();
        for (Location location : list) {
        	System.out.println(location.toString());
        }
	} catch (Exception e) {    
		e.printStackTrace();    
	}
}

 

分享到:
评论

相关推荐

    thrift-spring-http代码实例

    本文借鉴spring对hessian的支持,实现spring对Thrift的支持。服务端主要使用了spring的HttpRequestHandler接口和RemoteExporter接口。HttpRequestHandler接口用于暴露http服务,这样就可以接受http的请求,这个如果...

    spring与thrift集成

    将 Spring 与 Thrift 集成,可以利用 Spring 的强大功能来管理和调度 Thrift 服务,同时借助 Thrift 实现高效的数据传输和跨语言服务调用。 集成 Spring 和 Thrift 主要涉及以下几个步骤: 1. **创建 Thrift IDL ...

    Thrift-server与spring集成

    当我们将Thrift与Spring集成时,我们可以利用Spring的强大功能来管理和协调Thrift服务,从而构建出高效、灵活的分布式系统。 集成Thrift和Spring的主要目的是为了利用Spring的依赖注入(DI)和面向切面编程(AOP)...

    thrift服务集成spring及连接池

    【Thrift服务集成Spring及连接池】的知识点详解 Thrift是一个开源的跨语言服务框架,由Facebook在2007年创建并贡献给了Apache基金会。它的主要目标是解决系统间的大数据量通信问题,同时支持多语言环境下的跨平台...

    thrift实现http协议案例

    在本案例中,“thrift实现http协议案例”是关于如何利用Thrift来处理HTTP协议通信的一个实践教程。 首先,让我们了解一下Thrift的基本工作原理。Thrift基于接口描述语言(IDL),开发者可以在IDL文件中定义服务接口...

    spring-cloud-starter-thrift:spring-cloud-starter-thrift提供SpringCloud对可伸缩的跨语言服务调用框架Apache Thrift的封装和集成

    spring-cloud-starter-thrift简介spring-cloud-starter-thrift提供Spring Cloud对可伸缩的跨语言服务调用框架Apache Thrift的封装和集成。spring-cloud-starter-thrift包括客户端spring-cloud-starter-thrift-client...

    Apache Thrift 初学小讲(六)【spring】

    在本篇小讲中,我们将探讨如何将Thrift与Spring框架结合,以便于构建微服务架构。 首先,让我们了解Thrift的基本工作原理。Thrift IDL(接口定义语言)允许开发者声明服务方法和数据类型,类似于Java中的接口或C++...

    海豚:基于spring boot支持thrift序列化的http的微服务框架

    海豚基于spring boot支持thrift序列化的http的微服务框架特征支持thrift序列化的http协议兼容spring cloud ribbon配置支持基于ribbon负载均衡的retryRetryLoadBalancerInterceptor快速开始客户1.springboot启动时...

    Spring集成Thrift--Server AND Client

    在IT行业中,Spring框架是Java领域最常用的轻量级应用框架之一,而Thrift则是一种跨语言的服务框架,由Facebook开源。本篇文章将探讨如何在Spring框架中集成Thrift,构建一个Server和Client,以便在分布式系统中实现...

    spring-thrift-starter:一组很酷的注释,可帮助您使用Spring Boot构建Thrift应用程序

    适用于Spring Boot的Apache Thrift Starter 一组很酷的注释,可帮助您使用Spring Boot构建Thrift应用程序。如何连接项目非常简单: repositories { jcenter()}compile ' info.developerblog.spring.thrift:spring-...

    thrift-Demo

    此外,Thrift还提供了传输层的实现,如TCP、HTTP等,你可以选择适合你的传输方式。在实际应用中,通常会结合服务器框架,如Java的Jetty或C++的libevent,来构建完整的服务器。 "thrift-Demo"的压缩包可能包含了以下...

    Java基于Spring Boot、Thrift、Zookeeper实现的RPC框架

    基于Thrift、zookeeper的rpc实现 基于注解配置ThriftService、ThriftReference 基于权重的简单负载均衡 使用TMultiplexedProcessor发布多个服务

    spring-thrift-integration:示例如何将Thrift集成到Spring应用程序中

    Spring节俭整合 这是一个示例,展示了如何在不使用Spring Boot的情况下将集成到Spring应用程序中。 相反,它依赖于Spring的WebApplicationInitializer类,因此不需要web.xml。 如何建造 让Maven编译代码: mvn ...

    thrift通过http传输的java例子

    在这个“thrift通过http传输的java例子”中,我们将深入探讨Thrift如何与HTTP协议结合,以及如何在Java环境中实现这一过程。 首先,我们需要理解Thrift的核心概念:服务定义。在Thrift IDL文件中,我们可以定义服务...

    the programmer's guide to apache thrift

    With support for over 15 programming languages, Apache Thrift can play an important role in a range of distributed application development environments. As a serialization platform Apache Thrift ...

    使用wireshark抓取thrift协议接口调用

    总之,结合Wireshark和Thrift dissector,我们可以深入洞察Thrift协议的网络交互,这对于开发、调试和维护Thrift服务具有极大的价值。请确保正确配置和使用这些工具,以便充分利用它们的功能,提升你的工作效率。

    Thrift-java学习小结

    Thrift是Facebook开源的一款高性能、跨语言的服务框架,它的设计目标是高效地在不同编程语言之间进行通信。本文将基于Thrift的Java实现,总结学习过程中的一些关键知识点,旨在帮助理解Thrift的工作原理以及如何在...

    thrift-0.13.0.zip

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年创建,现在是Apache软件基金会的项目。它的主要目标是通过定义一种中间语言(IDL,Interface Definition Language)来简化不同编程语言之间的通信,使得...

    thrift环境搭建(内附thrift运行环境可执行程序、搭建说明文本)

    对于Unix-like系统(如Linux或macOS),进入解压后的目录,执行以下命令来编译和安装Thrift: ``` ./bootstrap.sh ./configure make sudo make install ``` 对于Windows,你可以使用Cygwin或者Visual Studio...

Global site tag (gtag.js) - Google Analytics