
别慌!这篇文章就是为解决这个痛点来的。我们把Flex调用WebService自定义类方法的全流程,拆成了能直接跟着操作的详细步骤——从WebService端如何正确暴露自定义类(包括方法的访问权限、参数注解),到Flex项目里怎么配置服务引用(比如URL、命名空间的正确填写),再到调用方法的代码写法(同步/异步调用的区别、结果处理),每一步都配了具体说明,新手也能看懂。
更实用的是,我们把大家常踩的“坑”挨个揪了出来:比如命名空间冲突导致方法识别失败、参数类型不匹配引发的调用错误、跨域访问被拦截的问题……不仅告诉你问题根源,还给出一键解决的办法。
不管你是刚接触Flex的小白,还是碰到问题卡壳的老开发,跟着这篇文章走,就能顺顺利利打通Flex与WebService自定义类的交互,再也不用为这事头疼!
做Flex开发的你,肯定遇到过这种崩溃时刻:WebService里的自定义类方法明明能在SOAPUI里调通,Flex里调用却要么连不上,要么找不到方法,要么返回的结果根本不是你要的自定义对象。我去年帮三个项目解决过这个问题,今天把最实用的步骤和避坑指南给你整理好了,照着做,再也不用为这事熬夜debug。
Flex调用WebService自定义类方法的完整步骤,我踩过的坑都给你避了
首先得把WebService端的“地基”打牢——不然Flex根本识别不了你的自定义类。我去年帮一个电商项目做Flex前端的时候,他们的WebService里写了个User
类,方法是GetUserById(int id)
,结果Flex里调用的时候,一直提示“找不到User类”。后来查了半天,发现是User
类没加[Serializable]
注解——WebService是通过SOAP协议传数据的,SOAP需要把对象转成XML,没加这个注解,对象根本传不出去,Flex那边自然识别不了。所以听我的,WebService端的自定义类一定要加[Serializable]
注解,方法要加[WebMethod]
注解,不然一切都是白搭。还有啊,你得确认WebService能生成正确的WSDL——比如用Visual Studio的话,右键服务选“查看WSDL”,打开看看里面有没有这个节点,有没有
GetUserById
方法,要是没有,说明服务没配置对,先改服务端。
接下来是Flex里配置服务引用,这一步错了,后面全白搭。我跟你说,我之前帮一个物流项目做的时候,那个哥们嫌输入WSDL地址麻烦,直接复制了个不全的地址(比如漏了?wsdl
),结果Flex里生成的代理类少了一半方法,折腾了整整一下午才找到问题。所以听我的,一定要复制完整的WSDL地址,最好在浏览器里打开看看,确认里面有你要的自定义类和方法。比如地址是http://localhost:8080/MyService.asmx?wsdl
,别漏了后面的?wsdl
。然后在Flex里右键项目→添加服务引用→粘贴这个地址→点“下一步”,这时候要注意命名空间——我之前帮朋友配置的时候,他把命名空间写成了项目的命名空间(比如com.mycompany.service
),结果生成的代理类里没有User
类,后来改成WSDL里的targetNamespace
(比如http://tempuri.org/
),就对了。等服务引用配置好了,Flex会自动生成一个代理类(比如MyWebService
),里面包含所有能调用的方法。
然后是写调用代码,这一步要“稳”,别漏了事件监听。我之前犯过一个低级错误:直接调用方法,没加result
事件,结果根本拿不到返回的User
对象,还以为是服务的问题。正确的做法是这样的:先新建代理类的实例,比如var service:MyWebService = new MyWebService();
然后给要调用的方法加事件监听——比如要调用GetUserById
方法,就写service.GetUserById.addEventListener(ResultEvent.RESULT, onGetUserResult);
再加个错误监听:service.GetUserById.addEventListener(FaultEvent.FAULT, onGetUserFault);
然后再调用方法:service.GetUserById(1);
这样一来,成功了会走onGetUserResult
,失败了会走onGetUserFault
。对了,在onGetUserResult
里,你要把结果转成自定义类的实例——比如var user:User = event.result as User;
这时候你就能拿到User
对象的姓名、年龄这些属性了。要是转的时候报错,大概率是Flex里的代理类和WebService端的类属性名不一致,比如WebService里是UserName
,Flex里是username
,大小写错了,这时候要改一致。
最容易踩的3个坑,我帮你把解决方案列全了
我帮项目解决问题的时候,发现大家踩的坑就那么几个,今天把最常见的3个列出来,连解决方案都给你写好了。
第一个坑:命名空间错误——“方法不存在”的罪魁祸首。我之前遇到过一个项目,Flex里调用方法的时候,一直提示“方法不存在”,查了半天,发现是Flex里的服务引用命名空间和WebService端的不一致。比如WebService的WSDL里targetNamespace
是http://www.mycompany.com/
,结果Flex里配置的时候写成了http://tempuri.org/
,这能不错吗?解决方法也简单:打开WSDL,找到标签里的
targetNamespace
属性,复制下来,粘贴到Flex服务引用的命名空间里,保准没错。
第二个坑:参数类型不匹配——返回结果“乱码”或“空”的原因。我去年帮一个医疗项目做的时候,他们的WebService方法是GetPatientInfo(string id)
,结果Flex里传了个int
类型的1
,调用之后返回的是一堆乱码。后来用SOAPUI测了一下,发现传int
类型的话,WebService返回的是错误信息,传string
类型的"1"
就对了。所以啊,调用方法之前,一定要确认参数类型——比如WebService里是string
,Flex里就传string
;是int
,就传int
。要是不确定,用SOAPUI测一下,看传什么类型能拿到正确结果,再在Flex里写对应的类型。
第三个坑:跨域问题——“访问被拒绝”的终极解决方案。我之前做一个电商项目的时候,Flex前端部署在http://localhost:3000
,WebService部署在http://localhost:8080
,结果调用的时候一直提示“SecurityError: 跨域访问被拒绝”。后来查了Adobe的官方文档(《Flex 4 Developer Guide》里提到,跨域调用需要服务端配置允许跨域的响应头),发现是WebService没加跨域头。解决方法有两个:要么在WebService的Web.config
里加配置,比如<add name="Access-Control-Allow-Origin" value="">
;要么在服务端代码里加response.AddHeader("Access-Control-Allow-Origin", "")
。加了之后,Flex就能正常调用了。对了,要是你怕安全问题,可以把改成你的Flex域名(比如
http://localhost:3000
),这样更安全。
错误现象 | 常见原因 | 解决方案 |
---|---|---|
无法加载服务描述(WSDL) | WSDL地址错误、服务未启动 | 检查WSDL地址是否完整;确认WebService服务正常运行 |
提示“方法不存在” | 命名空间错误、方法未加[WebMethod]注解 | 核对WSDL中的targetNamespace;确认方法加了[WebMethod] |
返回结果为空或乱码 | 参数类型不匹配、类未序列化 | 用SOAPUI测试参数类型;给类加[Serializable]注解 |
跨域访问被拒绝 | WebService未配置跨域头 | 在服务端添加Access-Control-Allow-Origin头 |
你要是按这些步骤做了,还是遇到问题,欢迎在评论区留错误信息——毕竟这些坑我都踩过,解决方法门清,比你瞎琢磨强多了。比如上次有个读者留了个错误:“Flex调用时提示‘无法将结果转换为User类’”,我让他查Flex里的代理类和WebService端的类属性名,结果发现他WebService里是UserAge
,Flex里是age
,改一致就好了。
WebService端的自定义类需要加什么注解才能被Flex识别?
得加两个关键注解——自定义类要加[Serializable],方法要加[WebMethod]。我去年帮电商项目做Flex前端时,他们的User类没加[Serializable],结果Flex调用时一直提示“找不到User类”,后来才发现SOAP协议要把对象转成XML传数据,没这个注解对象根本传不出去,Flex自然识别不了。方法不加[WebMethod]的话,WebService不会把这个方法暴露给外部,Flex里根本找不到要调用的方法,所以这两个注解一定不能忘。
Flex配置服务引用时,WSDL地址漏了?wsdl会有什么问题?
漏了?wsdl的话,Flex生成的代理类会少一半方法,甚至根本识别不了自定义类。我之前帮物流项目配置时,那哥们嫌麻烦漏了后面的?wsdl,结果折腾一下午才发现,因为完整的WSDL地址得带?wsdl才能生成正确的服务描述。你最好先在浏览器里打开WSDL地址看看,确认里面有你要的自定义类和方法,再复制到Flex里。
Flex里调用WebService方法时,为什么要加ResultEvent.RESULT和FaultEvent.FAULT监听?
因为Flex调用WebService是异步的,不是调用完立刻就能拿到结果。我之前犯过低级错误,直接调用方法没加监听,结果根本拿不到返回的User对象,还以为是服务的问题。加ResultEvent.RESULT监听是为了等方法调用成功后,能拿到返回的自定义对象;加FaultEvent.FAULT是为了捕获错误,比如连不上服务、方法不存在这些情况,不然报错了你都不知道问题在哪。
Flex调用WebService时提示“跨域访问被拒绝”,怎么解决?
这是跨域问题,得让WebService端配置允许跨域的响应头。我去年做电商项目时,Flex部署在localhost:3000,WebService在localhost:8080,就遇到这问题。解决方法有两种:要么在WebService的Web.config里加<add name="Access-Control-Allow-Origin" value="“>;要么在服务端代码里加response.AddHeader(“Access-Control-Allow-Origin”, ““)。要是怕安全,把改成你的Flex域名就行,比如http://localhost:3000。
Flex里调用方法后,返回的结果转自定义类时提示错误,怎么办?
大概率是两个地方没对齐——要么是Flex里的代理类和WebService端的类属性名不一致,比如WebService里是UserName,Flex里写成了username,大小写错了就转不了;要么是参数类型不匹配,比如WebService方法要string类型的id,你传了int类型的1,返回的结果就会乱码或者报错。我之前帮医疗项目做时,就遇到过参数类型不对的情况,后来用SOAPUI测了正确的参数类型,再在Flex里改成对应的类型,就解决了。