使用 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(); 
    } 
} 

一些引用资料:
  • Use wsdlLocation as a path prefix for multiple WSDL URLs
  • Why does jax-ws need access to wsdl at runtime?
  • Search for "Why does jax-ws need access to wsdl at runtime"
  • Jax-ws client requires WSDL file at runtime ?

  • 评论关闭
    IT干货网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!