使用 wsimport 生成 JAX-WS 客户端后
wsimport -keep WebService.wsdl
JAX-WS 必须在运行时查找 wsdl 位置的原因是什么?
这是一个错误吗?
我发现了这个很棒的帖子:
JAX-WS client : what's the correct path to access the local WSDL?
但它没有说明为什么我们在运行时需要 wsdl
请您参考如下方法:
我想,也许你需要一个代码解决方案。以下解决方案要求您将 WSDL 文件存储在资源文件夹中,其中是 maven 类项目的资源文件夹。
@Bean
public WeatherWebServiceServiceSoap weatherWebServiceServiceSoap() throws Exception{
URL wslLocation = generatedWsdlLocation();
if(log.isDebugEnabled()) {
log.debug("WSDL Location: " + wslLocation.toString());
}
// cover wslLocation with the arg constructor
WeatherWebServiceService weatherWebServiceService = new WeatherWebServiceService(wslLocation);
weatherWebServiceService.setHandlerResolver(
portInfo -> webServiceSOAPHandlerList.stream().map(s -> (Handler)s).collect(Collectors.toList()));
WeatherWebServiceServiceSoap serviceSoap = weatherWebServiceService.getWeatherWebServiceServiceSoap();
BindingProvider bindingProvider = ((BindingProvider)serviceSoap);
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
wsdlProperties.getAddressLocation());
return serviceSoap;
}
private URL generatedWsdlLocation() throws MalformedURLException {
URL baseUrl = ClassUtil.getLocation(this.getClass());
// the value of WebServiceConstants.WEATHER_WSDL_RESOURCES_LOCATION should be the relative path of your wsdl in resources(e.g. src/main/resources/wsdl, then the value should be wsdl/).
return new URL(baseUrl, WebServiceConstants.WEATHER_WSDL_RESOURCES_LOCATION);
}
ClassUtil
允许您在 jarFile 中获取存储 wsdl 文件的类路径。
/**
* ref: https://github.com/scijava/scijava-common/blob/scijava-common-2.62.1/src/main/java/org/scijava/util/ClassUtils.java#L296-L355
*/
@Slf4j
public class ClassUtil {
/**
* get the jar classes path where the <code>clazz</codee> belongs to.
*
* <p>
* if in file system(e.g. /path/to/package/TheClass.class) return file directory (e.g. file:/path/to); if in jar (e.g.
* /path/to/the-jar.jar!/the/package/TheClass), return path in jar( e.g. jar:file:/path/to/the-jar.jar!/BOOT-INF/classes!/)
* return null when error occured.
* </p>
*/
public static URL getLocation(Class<?> clazz) {
if (clazz == null) {
// could not load the class
return null;
}
try {
URL codeSourceLocation = clazz.getProtectionDomain().getCodeSource().getLocation();
if (codeSourceLocation != null) {
return codeSourceLocation;
}
} catch (Exception e) {
// SecurityException: Cannot access protection domain.
// NullPointerException: Protection domain or code source is null.
}
final URL classResource = clazz.getResource(clazz.getSimpleName() + ".class");
if (classResource == null) {
// cannot find class resource
return null;
}
String url = classResource.toString();
// java.io.File -> java/io/File.class
String suffix = clazz.getCanonicalName().replace('.', '/') + ".class";
if (!url.endsWith(suffix)) {
if (isDebugEnable()) {
log.debug("Weired URL: {} should end with {}", url, suffix);
}
// weired URL
return null;
}
String classesUrl = url.substring(0, url.length() - suffix.length());
try {
return new URL(classesUrl);
} catch (MalformedURLException e) {
if (isDebugEnable()) {
log.debug(e.getMessage(), e);
}
return null;
}
}
public static URL getFileLocation(Class<?> clazz) {
URL url = getLocation(clazz);
if(url == null) {
return url;
}
String path = url.toString();
if(path.startsWith("jar:")) {
// remove "jar:" prefix and "!/" suffix
path = path.substring(4, path.length() - 2);
}
try {
return new URL(path);
} catch (MalformedURLException e) {
if (isDebugEnable()) {
log.debug(e.getMessage(), e);
}
return null;
}
}
private static boolean isDebugEnable() {
return log.isDebugEnabled();
}
}
一些引用资料: