Exception:两个类具有相同的 XML 类型名称,请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称...

本文探讨了在WebService开发过程中,因方法返回值与XML类型名称相同导致的异常问题。提出了通过修改方法名或使用JAXB注解指定不同名称的方法,并讨论了客户端代码生成时可能遇到的问题及解决方案。
部署运行你感兴趣的模型镜像

两个类具有相同的 XML 类型名称

"{http://service.webservice.base.xm/}searchAccountBatchResponse"。

请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。

this problem is related to the following location:
at xm.base.webservice.model.SearchAccountBatchResponse

at private xm.base.webservice.model.SearchAccountBatchResponse xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse._return

at xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse
this problem is related to the following location:

at xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse


在进行webservice开发的时候,启动tomcat后报了如上异常。

@WebMethod
	public SearchAccountBatchResponse searchAccountBatch(@WebParam(name = "searchAccountBatchRequest") SearchAccountBatchRequest searchAccountBatchRequest){}
先观察这个方法,这个方法在生成wsdl文件时会生成如下两行:

<xs:element name="searchAccountBatch" type="tns:searchAccountBatch"/>
<xs:element name="searchAccountBatchResponse" type="tns:searchAccountBatchResponse"/>

第一行表示这个方法,第二行是jax_ws在解析时会根据每一个方法名生成一个对应的元素,名称为:方法名+Response,在这里就是searchAccountBatchResponse

为了验证这一点,写如下方法:

@WebMethod
	public ResultBase oilStationInfoSyn(StationsInfo stationsInfo){****}
这个可以正常运行并生成wsdl文件,对应的那两行的内容为:

<xs:element name="oilStationInfoSyn" type="tns:oilStationInfoSyn"/>
<xs:element name="oilStationInfoSynResponse" type="tns:oilStationInfoSynResponse"/>

也就是说上面的说法成立,我们得出如下结论:

结论1:jax_ws在解析时会根据每一个方法名生成一个对应的元素,名称为:方法名+Response

————————————————————————————————————————————————————————

继续,该方法的返回值为SearchAccountBatchResponse,在生成wsdl文件时会生成如下代码:

<xs:complexType name="searchAccountBatchResponse">
<xs:sequence>
<xs:element minOccurs="0" name="requestID" type="xs:string"/>
<xs:element minOccurs="0" name="returnCode" type="xs:string"/>
<xs:element minOccurs="0" name="returnMessage" type="xs:string"/>
<xs:element name="returnFlag" type="xs:boolean"/>
<xs:element name="isComplete" type="xs:boolean"/>
<xs:element name="accountInfoSize" type="xs:int"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="accountInfoList" nillable="true" type="tns:accountInfo"/>
</xs:sequence>
</xs:complexType>

当然,因为程序启动不起来,所以没办法看到生成的wsdl文件,所以仍然用刚才的那个类去验证,结果如下:

<xs:complexType name="resultBase">
<xs:sequence>
<xs:element minOccurs="0" name="ResultCode" type="xs:string"/>
<xs:element minOccurs="0" name="ExceptionMessage" type="xs:string"/>
<xs:element minOccurs="0" name="ResultMsg" type="xs:string"/>
</xs:sequence>
</xs:complexType>

SearchAccountBatchResponse和ResultBase是两个javabean,在生成wsdl文件时会生成对应的xml文件元素,其中类型名为类名的首字母小写,即searchAccountBatchResponse和resultBase于是我们的出下面的结论:
结论2:在生成wsdl文件时,返回值对应的javaBean会在wsdl文件中生成对应的元素,类型名为类名首字母小写后的结果

----------------------------------------------------------------------------------------------------------------------------

综合结论一和结论二,我们就可以发现报错的原因:因为程序试图在wsdl文件中写入两个类型名相同的元素

那我们该怎么解决呢?

-----------------------------------------------------------------------------------------------------------------------------

第一种方法是:修改方法名,理由应该是显而易见的,可以根据结论一得出

第二种方法是:使用JAXB的注解去指定返回值对应的javabean在生成的wsdl中对应的名字

由于接口的定义事先已经约定好了,所以排除第一种方法,先来试试第二种方法:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SearchAccountBatchResponse")
public class SearchAccountBatchResponse
{*****}
这种方法是指定该bean对应的wsdl的文件中的类型名为SearchAccountResponse,首字母是大写的,所以不会发生之前的异常。

程序可以正确运行,并可以访问到wsdl文件

----------------------------------------------------------------------------------------------------------------------------

难道这样就可以了吗?其实并没有 当我试图去生成客户端代码的时候出现了如下异常:


当然,因为我的这个接口里有多个方法,所以报的不是同一个方法的错,只报了其中的一个,这个是我用Myeclipse生成客户端是出现的,当我用cxf的wsdl2java 命令去生成客户端时,也会报同样的错。

很纠结,是什么原因呢?这是因为wsdl中存在一个SearchAccountResponse和一个searchAccountResponse,在生成对应的java类时自然都是首字母大写,即生成SearchAccountResponse.java,当程序试图生成两个同样的类时,就会报这个错:类或接口已经存在了

--------------------------------------------------------------------------------------------------------------------

上面的问题得分情况解决:

1.如果服务端已经写好了,我们是根据现有的wsdl文件去生成客户端,那我们只能使用wsdl的如下命令:

wsdl2java-autoNameResolutionwsdl地址
会对类进行重新命名,在执行命令的目录下会生成客户端代码,如下:


这是自动命名的结果。


2.如果我们是开发服务端的,现在仅仅是为了测试,那我们最好通过沟通来修改接口定义,修改方法返回值的名字,为了节省工作量,可以直接修改返回值对应的bean上的注解,如将前面代码修改为:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SearchAccountBatchResult")
public class SearchAccountBatchResponse
{*******}


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

这次可以总结到的最重要的结论是:接口的返回值不要以response结尾,即使想这样做,也不要造成 "方法名+Response =返回值名” 的情况出现。

最后要说的就是:“接口规范是谁定义的,出来,让我踹你两脚发火

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

package com.ckkbatch.batchutil; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import java.rmi.RemoteException; import java.util.Date; public class CkkInterface { private static String url= CKKPropertiesUtil.name; private static Service serv = new Service(); private static Call call; static { try { call = (Call)serv.createCall(); } catch (ServiceException e) { throw new RuntimeException(e); } call.setTargetEndpointAddress(url); call.setUseSOAPAction(true); call.setTimeout(new Integer(5000000)); call.setSOAPActionURI("webservice"); call.setOperationName(new QName("webservice","onSendMessage")); call.addParameter("bsId", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("bsMsg", XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); } public static String Webservice(String bsId,String bsMsg) { String remag=""; // try { //// call = (Call)serv.createCall(); //// call.setTargetEndpointAddress(url); //// call.setUseSOAPAction(true); //// call.setTimeout(new Integer(5000000)); //// call.setSOAPActionURI("webservice"); //// call.setOperationName(new QName("webservice","onSendMessage")); //// call.addParameter("bsId", XMLType.XSD_STRING, ParameterMode.IN); //// call.addParameter("bsMsg", XMLType.XSD_STRING, ParameterMode.IN); //// call.setReturnType(XMLType.XSD_STRING); // System.out.println(bsId); // System.out.println(bsMsg); // remag = (String)call.invoke(new Object[]{bsId,bsMsg}); // } catch (RemoteException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } try { return (String)call.invoke(new Object[]{bsId,bsMsg}); } catch (RemoteException e) { throw new RuntimeException(e); } } }
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值