3

我想构建一个将在 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;
}

}

作为 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。

任何帮助将不胜感激。谢谢。

4

1 回答 1

1

我也在尝试这样做(构建一个将在 Java SE 6.0 中运行的 JAX-WS Web 服务(没有容器,只是标准版 java)),我找到了一种最简单的方法。请查看这两个教程http://www.ibm.com/developerworks/webservices/tutorials/ws-eclipse-javase1/index.htmlhttp://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/

于 2013-09-14T17:41:59.020 回答