我想构建一个将在Java SE 6.0中运行的JAX-WS Web服务(没有容器,只有标准版java)。
我开始使用此处描述的旧教程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;
}
}
QueryParts1Request类是queryParts1()方法的一个参数,但是没有生成,如下所示:
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。
非常感谢任何帮助。感谢。
答案 0 :(得分:1)
我也试图这样做(构建一个将在Java SE 6.0中运行的JAX-WS Web服务(没有容器,只是标准版java)),我发现了一种最简单的方法。请查看这两个教程http://www.ibm.com/developerworks/webservices/tutorials/ws-eclipse-javase1/index.html和http://technology.amis.nl/2009/06/05/publish-a-webservice-from-a-poja-plain-old-java-application-that-is-out-of-the-container-using-endpoint-class/