Java SE 6.0 (コンテナーなし、Standard Edition Java のみ) で実行される JAX-WS Web サービスを構築したいと考えています。
ここで説明されている古いチュートリアルから始めましたhttp://today.java.net/pub/a/today/2007/07/03/jax-ws-web-services-without-ee-containers.html
しかし、私はいくつかの問題に直面しています。
WebService クラス (acximImpl) に対して wsgen を実行すると、操作メソッドのクラス ファイルと操作から返されるクラスが生成されますが、操作メソッドにパラメーターとして渡されるクラスのコードは生成されません。
そのため、クライアントを使用して queryParts1() メソッドを呼び出すと、「{http://com/activant/web/services/partorder}queryParts1Request のディスパッチ メソッドが見つかりません」というソープ エラーが返されます。
NetBeans IDE 7.0.1 を使用しています
NetBeans によって実行される build.xml は次のようになります (netbeans がクラス ファイルをコンパイルした後に実行されます)。
<project name="acximserver" default="default" basedir=".">
<description>Builds, tests, and runs the project acximserver.</description>
<import file="nbproject/build-impl.xml"/>
<target name="-post-compile" >
<echo message="Generating artifacts..."/>
<exec executable="C:/acxim/BuildTools/JAX-WS/2.2.3/bin/wsgen.bat">
<env key="JAVA_HOME" value="C:\BuildTools\jdk\1.6.0.24"/>
<arg value="-verbose"/>
<arg value="-keep"/>
<arg value="-cp"/>
<arg value="C:/Connectivity/APFCLSDK/Components/acximserver/build/classes"/>
<arg value="-d"/>
<arg value="${annotation.processing.source.output}"/>
<arg value="com.epicor.acximsdk.acximserver.acximImpl"/>
</exec>
<javac debug="true"
srcdir="${annotation.processing.source.output}"
destdir="C:/Connectivity/APFCLSDK/Components/acximserver/build/classes"
classpath="${acxclasspath}"/>
</target>
私のメインクラスファイルは次のようになります。
package com.epicor.acximsdk.acximserver;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import javax.xml.bind.annotation.XmlElement;
import org.apache.log4j.Logger;
public class Acximserver {
private Endpoint endpoint = null;
private static final Logger logger = Logger.getLogger("com.epicor.acximsdk.acximserver");
public Acximserver() {
System.out.println("Acximserver constructor called.");
endpoint = Endpoint.create(new acximImpl());
logger.info("Inside Acximserver constructor");
}
private void publish() {
endpoint.publish("http://localhost:1970/acximservice/PartOrderMgr");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("Acximserver main() function called");
Acximserver acxim = new Acximserver();
acxim.publish();
System.out.println("Acximserver Open for business at:");
System.out.println(" http://localhost:1970/acximservice/PartOrderMgr");
}
}
私の WebService クラスは次のようになります。
package com.epicor.acximsdk.acximserver;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import javax.xml.bind.annotation.XmlElement;
import javax.jws.HandlerChain;
@WebService(
name = "acximservice",
serviceName = "PartOrderMgr",
targetNamespace = "http://com/activant/web/services/partorder"
)
@HandlerChain(file="soaphandler.xml") // Setup some custom classes to intercept messages for logging.
public class acximImpl {
public acximImpl() {
System.out.println("acximImpl constructor called.");
}
@WebMethod(operationName = "queryParts1")
@WebResult(name = "queryParts1Response")
public QueryParts1Response queryParts1(
@WebParam(name = "Credentials", header = true) Credentials credentials,
@WebParam(name = "queryParts1Request") @XmlElement(required = true) QueryParts1Request request
//Credentials credentials,
//QueryParts1Request request
)
{
String tracknum = "";
QueryParts1Response response = new QueryParts1Response();
if(credentials != null) {
System.out.println("Token = " + (credentials.getToken()==null ? "null" : credentials.getToken()));
System.out.println("TokenSignature = " + (credentials.getTokenSignature()==null ? "null" : credentials.getTokenSignature()));
} else
System.out.println("credentials is null");
if(request != null) {
if(request.metadata != null) {
System.out.println("timeout = " + request.metadata.gettimeout());
System.out.println("ACXTrackNum = " + (request.metadata.getACXTrackNum()==null ? "null" : request.metadata.getACXTrackNum()));
if(request.metadata.getACXTrackNum() != null)
tracknum = request.metadata.getACXTrackNum();
}
else {
System.out.println("metadata is null");
}
if(request.requestString != null)
System.out.println("reqeust = " + request);
else
System.out.println("requestString is null");
}
else
System.out.println("request is null");
response._return = createACXNotification("buyid", "sellid", tracknum, "INFO", "0", "Service is working");
return response;
}
public String makeRequestHeader(String acxRequestName) {
return "<?xml version=\"1.0\" ?>" +
"<!DOCTYPE " + acxRequestName + " SYSTEM '" +
"http://www.aconnex.com/DTD" + "/" + acxRequestName +
"_v1_0" + ".dtd'>";
}
protected String createACXNotification(String Buy, String Sell, String Track, String Sev, String Code, String Msg) {
String version = "1.0"; // somehow make this configurable.
StringBuffer buf = new StringBuffer();
buf.append(makeRequestHeader("ACXNotificationResponse"));
buf.append("<ACXNotificationResponse><Envelope><BuyPartnerID>");
buf.append(Buy);
buf.append("</BuyPartnerID><DocVersNum>");
buf.append(version);
buf.append("</DocVersNum><DocGenBy>Epicor javaSDK</DocGenBy></Envelope>");
buf.append("<NotificationResponse><ACXTrackNum>");
buf.append(Track);
buf.append("</ACXTrackNum><SellPartnerID>");
buf.append(Sell);
buf.append("</SellPartnerID><Severity>");
buf.append(Sev);
buf.append("</Severity><Code>");
buf.append(Code);
buf.append("</Code><Msg>");
buf.append(Msg);
buf.append("</Msg></NotificationResponse></ACXNotificationResponse>");
return buf.toString();
}
}
生成される queryParts1() メソッドによって返されるクラス QueryParts1Response は、次のようになります。
package com.epicor.acximsdk.acximserver;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
//@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "queryParts1Response", propOrder = {
"_return"
})
@XmlRootElement(name = "queryParts1Response")
public class QueryParts1Response {
@XmlElement(name = "return", required = true)
protected String _return;
/**
* Gets the value of the return property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getReturn() {
return _return;
}
/**
* Sets the value of the return property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setReturn(String value) {
this._return = value;
}
}
queryParts1() メソッドのパラメーターであり、生成されない QueryParts1Request クラスは次のようになります。
package com.epicor.acximsdk.acximserver;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
//@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "http://com/activant/web/services/partorder", propOrder = {
"requestString",
"metadata"
})
@XmlRootElement(name = "queryParts1Request")
public class QueryParts1Request {
@XmlElement(name = "requestString", required = true)
protected String requestString;
@XmlElement(name = "metadata", required = true)
protected Metadata1TYPE metadata;
/**
* Gets the value of the requestString property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getRequestString() {
return requestString;
}
/**
* Sets the value of the requestString property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setRequestString(String value) {
this.requestString = value;
}
/**
* Gets the value of the metadata property.
*
* @return
* possible object is
* {@link Metadata1TYPE }
*
*/
public Metadata1TYPE getMetadata() {
return metadata;
}
/**
* Sets the value of the metadata property.
*
* @param value
* allowed object is
* {@link Metadata1TYPE }
*
*/
public void setMetadata(Metadata1TYPE value) {
this.metadata = value;
}
}
wsgen でメソッド パラメータ リスト内のオブジェクトのクラス ファイルを生成するにはどうすればよいですか? メイン クラスは EndPoint クラスを使用して、Web サービスがリッスンしている URL を公開していることに注意してください。
どんな助けでも大歓迎です。ありがとう。