Mic*_*rov 1 java xml soap cxf wsdl2java
简短问题:
我可以以某种方式绑定wsdl:port名称以在服务中生成自定义Java字段名称吗?
长问题:我有一个wsdl这样的部分:
<wsdl:service name="123xxx">
<wsdl:port name="123xxxHttpSoap11Endpoint" binding="tns:123xxxSoap11Binding">
<soap:address location="..."/>
</wsdl:port>
</wsdl:service>
Run Code Online (Sandbox Code Playgroud)
还有一个maven wsdl2java目标,它使用名称生成服务123xxx(我已经通过调用绑定来修复MyService),并在此服务中生成一个字段:
public class MyService extends Service {
...
public final static QName 123xxxHttpSoap11Endpoint =
new QName("http://new.webservice.namespace", "123xxxHttpSoap11Endpoint");
...
}
Run Code Online (Sandbox Code Playgroud)
这导致编译错误,因为变量不能以Java中的数字开头.我无法找到一种方法以某种方式自定义此生成的代码而不更改原始的wsdl.
那么,有没有办法通过cxf绑定绑定它,就像它与服务本身一样:
<bindings...>
<bindings node="wsdl:definitions/wsdl:service">
<class name="MyService"/>
</bindings>
</bindings>
Run Code Online (Sandbox Code Playgroud)
或者可能还有其他方法来实现这个目标?
最后我找到了解决方案.当然,这是常见的wsdl生成过程的开销,但它只是(或几乎只是)满足我的限制的方式.
首先,我检查了cxf库的来源,发现有一种生成Port元素的方法:
org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ServiceProcessor#processPort
Run Code Online (Sandbox Code Playgroud)
只JavaPort使用名称创建,从原始文件中获取wsdl并且不使用任何绑定处理它:
JavaPort jport = new JavaPort(NameUtil.mangleNameToClassName(port.getName().getLocalPart()));
Run Code Online (Sandbox Code Playgroud)
更进一步,我发现有可能注入自定义代码生成器,它负责java从cxf模型创建类.
经过一些研究,我发现这个答案帮助我做到了.
所以我用这样的类创建了一个单独的模块(检查注释):
//note that I've put my class inside the package,
//which is used for other default generators in cxf
package org.apache.cxf.tools.wsdlto.frontend.jaxws.generators;
import java.util.List;
import java.util.Map;
import org.apache.cxf.tools.common.ToolContext;
import org.apache.cxf.tools.common.ToolException;
import org.apache.cxf.tools.common.model.JavaPort;
import org.apache.cxf.tools.common.model.JavaServiceClass;
public class CustomSEIGenerator extends SEIGenerator {
@Override
public void generate(ToolContext penv) throws ToolException {
//no streams, because we still on java 7
//fetch all services
Map<String, JavaServiceClass> ss = penv.getJavaModel().getServiceClasses();
for (Map.Entry<String, JavaServiceClass> s : ss.entrySet()) {
//fetch all ports from each service
for (JavaPort port : s.getValue().getPorts()) {
//set custom name to each port
port.setName("_" + port.getName);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
并置于一个tools-plugin.xml到META-INF文件夹中:
<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns="http://cxf.apache.org/tools/plugin" name="play" version="" provider="play.typesafe.com">
<frontend name="sample" package="org.apache.cxf.tools.wsdlto.frontend.jaxws" profile="JAXWSProfile">
<container name="JAXWSContainer" package="org.apache.cxf.tools.wsdlto.frontend.jaxws" toolspec="jaxws-toolspec.xml"/>
<processor name="WSDLToJavaProcessor" package="org.apache.cxf.tools.wsdlto.frontend.jaxws.processor"/>
<builder name="JAXWSDefinitionBuilder" package="org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11"/>
<generators package="org.apache.cxf.tools.wsdlto.frontend.jaxws.generators">
<generator name="CustomSEIGenerator"/>
<generator name="AntGenerator"/>
<generator name="ClientGenerator"/>
<generator name="FaultGenerator"/>
<generator name="ImplGenerator"/>
<generator name="SEIGenerator"/>
<generator name="ServerGenerator"/>
<generator name="ServiceGenerator"/>
</generators>
</frontend>
</plugin>
Run Code Online (Sandbox Code Playgroud)
(请注意,我已将自定义生成器置于默认生成器之前,以使其与修改后的模型一起使用).
接下来,我刚刚根据上面发布的答案修改了我的pom文件,很高兴看到它正在运行.