最近在考虑java服务端与Flex客户端如何更加方便的交互。
首先想到的是AMF,其次是webservice。相比之下,webservice应用更加广泛。故在此先记录webservice的思路。有关AMF的研究将在后面的文章中记录。
为了保证代码简洁,这里使用sun 推出的JAX-WS实现方案。实现与flex客户端的上传与下载功能。
首先是webservice接口声明,注意:多个参数的情况下一定要加WebParam注解,否则只能识别第一个参数,其他参数将被忽略。
@WebService public interface ITestService { @WebMethod public String upload( @WebParam String filename, @WebParam byte[] bytes); @WebMethod public byte[] download(String filename); }
下面是接口实现代码,实现两个功能,处理上传二进制数据并保存,读取文件并返回。
@WebService(serviceName="test") @Service public class TestService implements ITestService { @Override public String upload(String filename, byte[] bytes) { FileOutputStream fos = null; try { File f = new File("/tmp",filename); System.out.println(f.getAbsolutePath()); fos = new FileOutputStream(f); fos.write(bytes); } catch (IOException e) { e.printStackTrace(); } finally{ if(fos!=null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } return filename; } @Override public byte[] download(String filename) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); FileInputStream fis = null; try { fis = new FileInputStream(new File("/tmp",filename)); byte[] bytes = new byte[1024]; int len = -1; while((len = fis.read(bytes))!=-1){ bos.write(bytes, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally{ if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } return bos.toByteArray(); } }
然后是与spring的集成,spring会自动帮我们扫描带有WebService注解的类并发布为服务。此处的IP设为0.0.0.0代表服务端的任何IP都能访问
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"> <property name="baseAddress" value="http://0.0.0.0:9080/ws/" /> </bean>
启动服务成功后,在浏览器里输入http://localhost:9080/ws/test?wsdl 进行验证
下面是Flex客户端的调用,也一并记录下来。
public class TestWsdl { private var ws:WebService = new WebService; public function TestWsdl(url:String) { ws.loadWSDL(url); } // 提示用户选择本地文件,并上传 public function upload():void { var fr:FileReference = new FileReference; fr.addEventListener(Event.COMPLETE, function():void { invoke("upload", function(rs:String):void { trace(rs," uploaded!"); }, fr.name,fr.data); } ); fr.addEventListener(Event.SELECT, function():void { fr.load(); } ); fr.browse(); } // 将文件下载到本地。此操作会弹出下载框 public function download():void { var fr:FileReference = new FileReference; var filename:String = "test.txt"; invoke("download", function(rs:ByteArray):void { fr.save(rs, filename); },filename ); } // 客户端调用的通用入口 public function invoke(methodName:String, callback:Function, ...args):void { ws.addEventListener(ResultEvent.RESULT, function(re:ResultEvent):void { callback && callback(re.result); ws.removeEventListener(ResultEvent.RESULT, arguments.callee); } ); ws.addEventListener(FaultEvent.FAULT, function(fe:FaultEvent):void { trace(fe.fault); ws.removeEventListener(FaultEvent.FAULT, arguments.callee); } ); var op:AbstractOperation = ws.getOperation(methodName); op.send.apply(op, args); } }
最后是Flex端的调用代码
private var client:TestWsdl = new TestWsdl("http://localhost:9080/ws/test?wsdl"); private function upload():void { client.upload(); } private function download():void { client.download(); }
至此,整个过程就完成了,当然这仅仅是一个开始,还有验证等一些更加复杂的操作。研究成熟以后再补上。