programing

JAX-WS 클라이언트: 로컬 WSDL에 액세스하기 위한 올바른 경로는 무엇입니까?

randomtip 2022. 12. 1. 23:27
반응형

JAX-WS 클라이언트: 로컬 WSDL에 액세스하기 위한 올바른 경로는 무엇입니까?

문제는 제공된 파일에서 웹 서비스 클라이언트를 구축해야 한다는 것입니다.이 파일을 로컬 파일 시스템에 저장하고 WSDL 파일을 올바른 파일 시스템 폴더에 보관하는 동안 모든 것이 정상입니다.서버에 전개하거나 파일시스템 폴더에서 WSDL을 삭제하면 프록시가 WSDL을 찾을 수 없어 오류가 발생합니다.웹을 검색했지만 다음 게시물을 찾을 수 없었습니다.
jarJAX-WS로부터의 로딩
http://www.java.net/forum/topic/glassfish/metro-and-jaxb/client-jar-cant-find-local-wsdl-0httpwww.java.net/forum/topic/glassfish/metro-and-jaxb/
http://blog.vinodsingh.com/2008/12/locally-packaged-wsdl.htmlhttpblog.vinodsingh.com/2008/12/.html

NetBeans 6.1(이 새로운 웹 서비스 클라이언트로 업데이트해야 하는 레거시 애플리케이션)을 사용하고 있습니다.JAX-WS 프록시 클래스를 다음에 나타냅니다.

    @WebServiceClient(name = "SOAService", targetNamespace = "http://soaservice.eci.ibm.com/", wsdlLocation = "file:/C:/local/path/to/wsdl/SOAService.wsdl")
public class SOAService
    extends Service
{

    private final static URL SOASERVICE_WSDL_LOCATION;
    private final static Logger logger = Logger.getLogger(com.ibm.eci.soaservice.SOAService.class.getName());

    static {
        URL url = null;
        try {
            URL baseUrl;
            baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
            url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
        } catch (MalformedURLException e) {
            logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
            logger.warning(e.getMessage());
        }
        SOASERVICE_WSDL_LOCATION = url;
    }

    public SOAService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public SOAService() {
        super(SOASERVICE_WSDL_LOCATION, new QName("http://soaservice.eci.ibm.com/", "SOAService"));
    }

    /**
     * @return
     *     returns SOAServiceSoap
     */
    @WebEndpoint(name = "SOAServiceSOAP")
    public SOAServiceSoap getSOAServiceSOAP() {
        return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class);
    }

    /**
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns SOAServiceSoap
     */
    @WebEndpoint(name = "SOAServiceSOAP")
    public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature... features) {
        return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class, features);
    }

}


은 프록시를 제입니다. :것것은 this this this this this this this this this this this this this this this this this this this this this this this this this this this 。

   WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class);
   // trying to replicate proxy settings
   URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource("");//note : proxy uses "."
   URL url = new URL(baseUrl, "/WEB-INF/wsdl/client/SOAService.wsdl");
   //URL wsdlUrl = this.getClass().getResource("/META-INF/wsdl/SOAService.wsdl"); 
   SOAService serviceObj = new SOAService(url, new QName(annotation.targetNamespace(), annotation.name()));
   proxy = serviceObj.getSOAServiceSOAP();
   /* baseUrl;

   //classes\com\ibm\eci\soaservice
   //URL url = new URL(baseUrl, "../../../../wsdl/SOAService.wsdl");

   proxy = new SOAService().getSOAServiceSOAP();*/
   //updating service endpoint 
   Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
   ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
   ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WebServiceUrl);

NetBeans는 WSDL 복사본을 web-inf/wsdl/client/SOAService에 저장하기 때문에 META-INF에도 추가하고 싶지 않습니다.서비스 클래스는 WEB-INF/classes/com/ibm/eci/soaservice/에 있으며 baseurl 변수에는 서비스 클래스에 대한 파일 시스템 풀패스(c:\path\to\the\project...)가 포함되어 있습니다.\soaservice.위의 코드는 에러를 발생시킵니다.

javax.xml.ws 를 참조해 주세요.Web Service Exception:file:/WEB-INF/wsdl/client/SOAService.wsdl에서 WSDL에 액세스하지 못했습니다.실패: \WEB-INF\wsdl\client\SOAService.wsdl(경로를 찾을 수 없습니다)

그럼 먼저 프록시 클래스의 wsdlocation을 업데이트할까요?WEB-INF/classes/com/ibm/eci/soaservice의 SOAService 클래스에 \WEB-INF\wsdl\client\에서 WSDL을 검색하도록 지시하려면 어떻게 해야 합니까?SOAService.wsdl?

편집: 다른 링크인 http://jianmingli.com/wp/?cat=41을 찾았습니다. 링크는 WSDL을 클래스 경로에 넣습니다.질문하기 부끄럽지만 웹 어플리케이션 클래스 패스에 삽입하려면 어떻게 해야 합니까?

가장 좋은 옵션은 jax-ws-catalog.xml을 사용하는 것입니다.

로컬 WSDL 파일을 컴파일 할 때 WSDL 로케이션을 덮어쓰고 다음과 같이 설정합니다.

http://localhost/wsdl/SOAService.wsdl

이것은 URI일 뿐 URL이 아닙니다.즉, 그 주소에서 WSDL을 사용할 필요가 없습니다.
wsdlocation의 wsdlocation Java의 wsdl의 wsdl.

그러면 프록시 코드가 에서 변경됩니다.

static {
    URL url = null;
    try {
        URL baseUrl;
        baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
        url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
    } catch (MalformedURLException e) {
        logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
        logger.warning(e.getMessage());
    }
    SOASERVICE_WSDL_LOCATION = url;
}

로.

static {
    URL url = null;
    try {
        URL baseUrl;
        baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
        url = new URL(baseUrl, "http://localhost/wsdl/SOAService.wsdl");
    } catch (MalformedURLException e) {
        logger.warning("Failed to create URL for the wsdl Location: 'http://localhost/wsdl/SOAService.wsdl', retrying as a local file");
        logger.warning(e.getMessage());
    }
    SOASERVICE_WSDL_LOCATION = url;
}

URL 생성자에서 알림 파일://이 http://로 변경되었습니다.

이제 jax-ws-catalog.xml로 제공됩니다.jax-ws-catalog.xml jax-ws가 없으면 WSDL이 실제로 로케이션에서 로드됩니다.

http://localhost/wsdl/SOAService.wsdl
and fail, as no such WSDL will be available.

단, jax-ws-catalog.xml을 사용하면 WSDL @에 접속하려고 할 때마다 로컬 패키지 WSDL로 jax-ws를 리다이렉트 할 수 있습니다.

http://localhost/wsdl/SOAService.wsdl
.

다음은 jax-ws-catalog.xml 입니다.

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
        <system systemId="http://localhost/wsdl/SOAService.wsdl"
                uri="wsdl/SOAService.wsdl"/>
    </catalog>

WSDL을 로딩해야 할 경우 항상 jax-ws에 알립니다.

http://localhost/wsdl/SOAService.wsdl
, it should load it from local path wsdl/SOAService.wsdl.

wsdl/SOAService?입니다.wsdl jax-ws-catalog.xml 만불불? 츠요시
META-INF 항아리

그러니까 이런 거

ABCD.jar|_ META-INF|_ jax-ws-syslog.xml|_ wsdl|_ SOAService.wsdl

이렇게 하면 프록시에 액세스하는 클라이언트의 URL을 재정의할 필요도 없습니다.WSDL은 JAR 내에서 선택되기 때문에 코드에 하드 코드화된 파일 시스템 경로를 포함할 필요가 없습니다.

jax-ws-syslog.xml에 대한 자세한 내용은http://http://jax-ws.java.net/nonav/2.1.2m1/docs/catalog-support.html 를 참조해 주세요.

도움이 되었으면 좋겠다

이 밖에 성공한 접근방식은 (Ant에서 Ant 태스크로) wsimport를 사용하여 WS 클라이언트프록시 코드를 생성하고 wsdlLocation 속성을 지정하는 것입니다.

<wsimport debug="true" keep="true" verbose="false" target="2.1" sourcedestdir="${generated.client}" wsdl="${src}${wsdl.file}" wsdlLocation="${wsdl.file}">
</wsimport>

여러 WSDL이 있는 프로젝트에서 이 작업을 수행하므로 스크립트는 $(wsdl)를 해결합니다.file} 값은 동적으로 /META-INF/wsdl/YourWebServiceName으로 설정됩니다.wsdl은 Java Source 로케이션에 상대적입니다(프로젝트 셋업 방법에 따라서는 /src).빌드 프로세스 중에 WSDL 및 XSD 파일이 이 위치에 복사되어 JAR 파일로 패키지됩니다.(위의 Bhasakar에서 설명한 용액과 유사)

MyApp.jar
|__META-INF
   |__wsdl
      |__YourWebServiceName.wsdl
      |__YourWebServiceName_schema1.xsd
      |__YourWebServiceName_schmea2.xsd

주의: WSDL 파일이 http URL이 아닌 Import된 XSD에 대한 상대적인 참조를 사용하고 있는지 확인합니다.

  <types>
    <xsd:schema>
      <xsd:import namespace="http://valueobject.common.services.xyz.com/" schemaLocation="YourWebService_schema1.xsd"/>
    </xsd:schema>
    <xsd:schema>
      <xsd:import namespace="http://exceptions.util.xyz.com/" schemaLocation="YourWebService_schema2.xsd"/>
    </xsd:schema>
  </types>

생성된 코드에는 다음과 같은 정보가 있습니다.

/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2-b05-
 * Generated source version: 2.1
 * 
 */
@WebServiceClient(name = "YourService", targetNamespace = "http://test.webservice.services.xyz.com/", wsdlLocation = "/META-INF/wsdl/YourService.wsdl")
public class YourService_Service
    extends Service
{

    private final static URL YOURWEBSERVICE_WSDL_LOCATION;
    private final static WebServiceException YOURWEBSERVICE_EXCEPTION;
    private final static QName YOURWEBSERVICE_QNAME = new QName("http://test.webservice.services.xyz.com/", "YourService");

    static {
        YOURWEBSERVICE_WSDL_LOCATION = com.xyz.services.webservice.test.YourService_Service.class.getResource("/META-INF/wsdl/YourService.wsdl");
        WebServiceException e = null;
        if (YOURWEBSERVICE_WSDL_LOCATION == null) {
            e = new WebServiceException("Cannot find '/META-INF/wsdl/YourService.wsdl' wsdl. Place the resource correctly in the classpath.");
        }
        YOURWEBSERVICE_EXCEPTION = e;
    }

    public YourService_Service() {
        super(__getWsdlLocation(), YOURWEBSERVICE_QNAME);
    }

    public YourService_Service(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    /**
     * 
     * @return
     *     returns YourService
     */
    @WebEndpoint(name = "YourServicePort")
    public YourService getYourServicePort() {
        return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class);
    }

    /**
     * 
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns YourService
     */
    @WebEndpoint(name = "YourServicePort")
    public YourService getYourServicePort(WebServiceFeature... features) {
        return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class, features);
    }

    private static URL __getWsdlLocation() {
        if (YOURWEBSERVICE_EXCEPTION!= null) {
            throw YOURWEBSERVICE_EXCEPTION;
        }
        return YOURWEBSERVICE_WSDL_LOCATION;
    }

}

아마 이것도 도움이 될 거야.이것은 단지 "카탈로그" 접근법을 사용하지 않는 다른 접근법일 뿐입니다.

아직 해결 방법을 찾고 있는 분들에게 가장 쉬운 해결책은<wsdlLocation>, 코드를 변경하지 않습니다.작업 단계는 다음과 같습니다.

  1. wsdl을 다음과 같은 리소스 디렉토리에 저장합니다.src/main/resource
  2. pom 파일에서 다음과 같이 wsdlDirectory와 wsdlLocation을 모두 추가합니다(wsdlLocation의 선두에 /를 놓치지 마십시오).wsdlDirectory는 코드 생성에 사용되며 wsdlLocation은 실행 시 동적 프록시를 생성하기 위해 사용됩니다.

    <wsdlDirectory>src/main/resources/mydir</wsdlDirectory>
    <wsdlLocation>/mydir/my.wsdl</wsdlLocation>
    
  3. 그런 다음 Java 코드(no-arg 컨스트럭터 포함):

    MyPort myPort = new MyPortService().getMyPort();
    
  4. 완성도를 높이기 위해 생성된 코드에 fluent api가 있는 full code generation part를 제공합니다.

    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.5</version>
    
    <dependencies>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-fluent-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-tools</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>
    
    <executions>
        <execution>
            <id>wsdl-to-java-generator</id>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <xjcArgs>
                    <xjcArg>-Xfluent-api</xjcArg>
                </xjcArgs>
                <keep>true</keep>
                <wsdlDirectory>src/main/resources/package</wsdlDirectory>
                <wsdlLocation>/package/my.wsdl</wsdlLocation>
                <sourceDestDir>${project.build.directory}/generated-sources/annotations/jaxb</sourceDestDir>
                <packageName>full.package.here</packageName>
            </configuration>
        </execution>
    </executions>
    

Bhaskar Karambelkar의 답변에 대해 자세히 설명하고 제 문제를 수정해 주셔서 감사합니다.그러나 나는 또한 고치는 것이 급하신 분들을 위해 세 가지 간단한 단계로 답을 다시 표현하고 싶습니다.

  1. wsdl 로컬 위치 참조를 다음과 같이 만듭니다.wsdlLocation= "http://localhost/wsdl/yourwsdlname.wsdl"
  2. src 바로 아래에 META-INF 폴더를 만듭니다.META-INF 아래의 폴더에 wsdl 파일을 넣습니다(예: META-INF/wsdl).
  3. 다음과 같이 META-INF 아래에 xml 파일 jax-ws-catalog.xml을 만듭니다.

    <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system"> <system systemId="http://localhost/wsdl/yourwsdlname.wsdl" uri="wsdl/yourwsdlname.wsdl" /> </catalog>

이제 항아리를 포장해.로컬 디렉토리는 더 이상 참조할 필요가 없습니다.모든 디렉토리가 패키지화되어 참조됩니다.

Spring을 사용하는 사용자는 classpath-protocol을 사용하여 클래스 경로 리소스를 참조할 수 있습니다.따라서 wsdlLocation의 경우 다음과 같이 됩니다.

<wsdlLocation>classpath:META-INF/webservice.wsdl</wsdlLocation>

이는 표준 Java 동작이 아닙니다.참고 항목: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html

여기에 기재되어 있는 것과 같은 문제를 안고 있었다.위의 예에 따라 WSDL 파일의 위치를 변경해도(이 경우 웹 서버에서), WSDL 파일은 서버 프로세스의 소스 트리에 내장된 원래 위치를 참조하고 있었습니다.

이 디버깅을 몇 시간 동안 시도한 결과 예외는 항상 같은 행에서 느려지는 것을 알 수 있었습니다(내 경우 41).결국 오늘 아침, 저는 제 소스 클라이언트 코드를 거래 파트너에게 보내기로 했습니다. 그래야 그들이 코드가 어떻게 보이는지 알 수 있지만, 그들만의 코드를 만들 수 있습니다.놀랍게도 클라이언트 소스 트리에서 클래스 파일이 .java 파일과 섞여 있는 것을 발견했습니다.정말 기괴하다!!JAX-WS 클라이언트 빌더 툴의 부산물이라고 생각합니다.

그 바보 같은 .class 파일을 zap으로 압축하고 클라이언트 코드를 완전히 청소하고 재구축하면 모든 것이 완벽하게 동작합니다!!리돈큘러스!!

YMMV, Andrew

여러 wsdl 파일을 사용하는 경우:

pom.xml

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<executions>
    <execution>
        <phase>generate-sources</phase>
        <goals>
            <goal>wsimport</goal>
        </goals>
        <configuration>
            <bindingDirectory>${basedir}/src/main/resources/jaxws</bindingDirectory>
            <bindingFiles>
                <bindingFile>binding.xjb</bindingFile>
            </bindingFiles>
            <wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
            <wsdlFiles>
                <wsdlFile>VN_PCSApplicationManagementService_v21.xml</wsdlFile>
                <wsdlFile>VN_PCSApplicationOfferManagementService_v7.xml</wsdlFile>
                <wsdlFile>VN_PCSOnlineDebtService_v2.xml</wsdlFile>
            </wsdlFiles>
        </configuration>
    </execution>
</executions>

서비스 클라이언트를 생성할 때:

@Bean
public ApplicationOfferManagementWSV7 getAppOfferWS() {
    String wsdlLocation = OnlineDebtWSv2Soap11QSService.class.getAnnotation(WebServiceClient.class).wsdlLocation().replaceFirst(".+wsdl/", "/wsdl/");
    URL url = this.getClass().getResource(wsdlLocation);
    ApplicationOfferManagementWSV7 applicationManagementWSV21 = new ApplicationOfferManagementWSV7Soap11QSService(url)
            .getApplicationOfferManagementWSV7Soap11QSPort();

    BindingProvider binding = (BindingProvider) applicationManagementWSV21;
    binding.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
    binding.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
    binding.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, offerEndpoint);

    return applicationManagementWSV21;
}

저 같은 경우에는 (= 제외)를 제거해야 했습니다..classpath 파일에서 "src" 엔트리에 대한 META-INF)를 실행한 후 Proxy 클래스에서 wsdl 경로를 /META-INF에서 META-INF로 변경했습니다.

언급URL : https://stackoverflow.com/questions/4163586/jax-ws-client-whats-the-correct-path-to-access-the-local-wsdl

반응형