背景:
arcgis 后台ae 10.x以下版本底层使用32位dll,故在拥ao java时指定jdk必须指定32位的,但目前不动产籍系统使用的是64位,造成冲突,解决办法之一就是将本人ao代码单独提出以webService形式提供功能支持,由于之前没系统接触过webService,故照葫芦画瓢过程中遇到了很多问题,在此记录下来,已利后事之师。
写法:目前webService写法多样,好处自不言语,本人使用的是服务端与客户端分离的策略。
问题1:
当webService以java web 形式启动的时候,例如tomcat,端口8080
String address = "http://hostIp:1234/ws_server/WebService";
EndPoint.publish(address,new ServiceImpl());
需要说明的是此处的端口1234是自己指定的只要与其他端口不冲突即可,后面地址路径也是自己指定的,如果与tomcat端口一只8080时将冲突;除此之外,new ServiceImpl()类ServiceImpl中,只能存放要发布的方法,其他不需要发布的方法不能写在此类中,建议多写一个接口类,类名@WebService 方法名用@WebMethod标注;第三,webservice只能接收和分发普通类型参数,当参数是复杂参数时,将出错,需要进行序列化操作,或者自己将复杂类型一一封装类,如Map
@XmlRootElement
Public class MapStringList{
private Map<String,ListRow> map;
@XmlElement
public Map<String,ListRow> getMap(){
return map;
}
public void setMap(Map<String,ListRow> map){
this.map = map;
}
}
问题二:
客户端代码片断
String namespace = "http://serviceImpl.szpl.com/"//从wsdl服务地址中可查看,貌似以包名反向命名的。
String endPoint = "http://10.10.12.149:1234/ws_server/WebService";//上述发布的地址
Service service = new Service();
Call call;
try{
call = (Call)service.createCall();
call.setTargetEndpointAddress(endPoint);
//调用的方法名
//call.setOperationName(new QName("http://serviceImpl.szpl.com/","getArea"));
call.setOperationName(new QName("http://serviceImpl.szpl.com/","getLocation"));
//call.setOperation("getArea");
//设置参数名
call.addParameter("arg0", XMLType.XSD_STRING,ParameterMode.IN);//注意点:arg0指的是第一个参,一次类推,不能指定其他参数名,也不能指定的和服务端参数一样的名称(一开始不太理解,为啥xml描述里没有参数名称描述,一度怀疑是不是自己写错了,其实webservice就是把服务端隐藏了,客户端只需要按顺序指定参数就可以了,无需关心服务端参数名称之类),否则服务端将接受不到参数。
//设置编码
call.setEncodingStyle("utf-8");
//设置返回类型
call.setReturnType(XMLType.XSD_STRING);
String result = (String)call.invoke(new Object[]{points});
System.out.println(result);
}catch(Exception e){
e.printStackTrace();
}
在导入jar包的时候千万别引用错了,需要多个jar包支持包括Common-logging等
webservice对参数要求高,有网友提出带下划线参数错误。
————————————-网友答案,在此感谢–
结合SoapUI分析发现,如果jws通过annotation来发布,或者类似方式,通过axis调用,需要注意两点:
1)在call.setOperationName是必须通过Qname来制定namespaceURI
2)在设定参数时,不使用服务端定义的参数名,而是arg0~argN来定义,也不需制定namespaceURI,上述代码
call.addParameter(new QName(namespace, “TransNo”), XMLType.XSD_STRING, ParameterMode.IN);
修改为
call.addParameter(“arg0”, XMLType.XSD_STRING, ParameterMode.IN);
有几个参数,即设定几个。