注:使用InputStream 作为方法参数的时候,需要将该参数作为方法的最后一个参数,否则会有问题
dubbo和hessian的maven依赖:
Java代码
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>dubbo</artifactId>
- <version>2.5.3</version>
- </dependency>
- <dependency>
- <groupId>com.caucho</groupId>
- <artifactId>hessian</artifactId>
- <version>4.0.7</version>
- </dependency>
服务提供者(项目名称:provider)
首先是web.xml配置(使用spring):
Xml代码
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:applicationContext.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <servlet>
- <servlet-name>dubbo</servlet-name>
- <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dubbo</servlet-name>
- <url-pattern>
- public InputStream download(String path);
- String upload(String destPath,InputStream in);
- }
服务实现类:
Java代码
- package com.tch.test.dubbo.service;
- import java.io.FileInputStream;
- import java.io.InputStream;
- public class DemoServiceImpl implements DemoService {
- @Override
- public InputStream download(String path) {
- System.out.println(path+"******************************");
- try {
- InputStream inputStream = new FileInputStream(path);
- return inputStream;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- @Override
- public String sayHello(String name) {
- return "Hello " + name;
- }
- @Override
- public String upload(String destPath,InputStream in) {
- try {
- //FileOutputStream out = new FileOutputStream("E:\\temp\\a.js");
- int n = -1;
- byte[] b = new byte[10240];
- while((n=in.read(b)) != -1){
- System.out.println(new String(b,0,n,"utf-8"));
- //out.write(b, 0, n);
- }
- //out.close();
- //out.flush();
- in.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "upload complete !";
- }
- }
最重要的applicationContext.xml :
参考:dubbo hessian协议
Xml代码
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
- <!-- 提供方应用信息,用于计算依赖关系 -->
- <dubbo:application name="hello-world-app" />
- <!-- 使用multicast广播注册中心暴露服务地址 -->
- <dubbo:registry address="multicast://224.5.6.7:1234" />
- <!-- 用hessian协议在8080(<span style="font-family: Arial, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 17.328125px; white-space: normal; background-color: #ffffff;">servlet容器的端口</span>)端口暴露服务,contextpath是项目名称,server这里是使用的web.xml里面配置的servlet -->
- <dubbo:protocol name="hessian" port="8080" contextpath="dubbo" server="servlet"/>
- <!-- 声明需要暴露的服务接口 -->
- <dubbo:service interface="com.tch.test.dubbo.service.DemoService" ref="demoService" />
- <!-- 和本地bean一样实现服务 -->
- <bean id="demoService" class="com.tch.test.dubbo.service.DemoServiceImpl" />
- </beans>
启动项目之后,就同时启动了服务。。。
下面是 consumer :
首先是服务接口:
Java代码
- package com.tch.test.dubbo.service;
- public interface DemoService {
- String sayHello(String name);
- public InputStream download(String path);
- String upload(String destPath,InputStream in);
- }
然后是applicationContext.xml :
Java代码
- <?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:dubbo="http://code.alibabatech.com/schema/dubbo"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd
- ">
- <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
- <dubbo:application name="consumer-of-helloworld-app" />
- <!-- 使用multicast广播注册中心暴露发现服务地址 -->
- <dubbo:registry address="multicast://224.5.6.7:1234" />
- <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
- <dubbo:reference id="demoService"
- interface="com.tch.test.dubbo.service.DemoService" />
- </beans>
好了,开始调用provider提供的服务:
Java代码
- package com.alibaba.dubbo;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.InputStream;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.alibaba.dubbo.demo.DemoService;
- public class Consumer {
- public static void main(String[] args) throws Exception {
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
- context.start();
- DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
- sayHello(demoService); //sayHello
- upload(demoService); //upload
- download(demoService); //download
- context.close();
- }
- //调用sayHello
- public static void sayHello(DemoService demoService){
- String result = demoService.sayHello(" dubbo "); // 执行远程方法
- System.out.println(result); // 显示调用结果
- }
- //调用upload
- public static void upload(DemoService demoService) throws FileNotFoundException{
- String result = demoService.upload("E:\\temp\\a.js",new FileInputStream("D:\\Program files\\apache-maven-3.1.0\\repository\\com\\caucho\\hessian\\4.0.7\\hessian-4.0.7.pom")); // 执行远程方法
- System.out.println(result); // 显示调用结果
- }
- //调用upload
- public static void download(DemoService demoService) throws Exception{
- String srcPath = "D:\\Program files\\apache-maven-3.1.0\\repository\\com\\caucho\\hessian\\4.0.7\\hessian-4.0.7.pom";
- InputStream inputStream = demoService.download(srcPath); // 执行远程方法
- byte b[] = new byte[1024];
- int n;
- try {
- while ((n = inputStream.read(b)) != -1) {
- System.out.print(new String(b,0,n,"utf-8"));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- inputStream.close();
- }
- }
- }
如果调用到download方法的时候,出现 java.io.IOException: stream is closed
则此时应该是jar包的问题,貌似这是hessian的一个bug : 关于该bug
解决方法下载hessian.jar的源码包,修改 com.caucho.hessian.client.HessianProxy :
在 Object value = in.readReply(method.getReturnType()); 这一句话之后加上下面代码:
Java代码
- if (value instanceof InputStream) {
- value = new ResultInputStream(conn, is, in, (InputStream) value);
- is = null;
- conn = null;
- }
然后重新打包,使用这个新的jar包就没问题了。。。
然后,就可以看到sayHello、下载、上传成功的结果了。。。