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.wsdland 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>
, 코드를 변경하지 않습니다.작업 단계는 다음과 같습니다.
- wsdl을 다음과 같은 리소스 디렉토리에 저장합니다.
src/main/resource
pom 파일에서 다음과 같이 wsdlDirectory와 wsdlLocation을 모두 추가합니다(wsdlLocation의 선두에 /를 놓치지 마십시오).wsdlDirectory는 코드 생성에 사용되며 wsdlLocation은 실행 시 동적 프록시를 생성하기 위해 사용됩니다.
<wsdlDirectory>src/main/resources/mydir</wsdlDirectory> <wsdlLocation>/mydir/my.wsdl</wsdlLocation>
그런 다음 Java 코드(no-arg 컨스트럭터 포함):
MyPort myPort = new MyPortService().getMyPort();
완성도를 높이기 위해 생성된 코드에 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의 답변에 대해 자세히 설명하고 제 문제를 수정해 주셔서 감사합니다.그러나 나는 또한 고치는 것이 급하신 분들을 위해 세 가지 간단한 단계로 답을 다시 표현하고 싶습니다.
- wsdl 로컬 위치 참조를 다음과 같이 만듭니다.
wsdlLocation= "http://localhost/wsdl/yourwsdlname.wsdl"
- src 바로 아래에 META-INF 폴더를 만듭니다.META-INF 아래의 폴더에 wsdl 파일을 넣습니다(예: META-INF/wsdl).
다음과 같이 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
'programing' 카테고리의 다른 글
PHP에서 배열의 선두에 항목을 삽입하려면 어떻게 해야 합니까? (0) | 2022.12.01 |
---|---|
배열에서 마지막 항목 제거 (0) | 2022.12.01 |
MariaDB를 사용하는 Ruby convert_tz가 0을 반환하고 있습니다. (0) | 2022.12.01 |
Mac OS X용 Java JDK 7 설치 후 - mvn - version에는 여전히 Java 버전 1.6.0_31이 표시됩니다. (0) | 2022.12.01 |
php의 mysql 테이블에서 count)를 선택합니다. (0) | 2022.11.22 |