java 为什么 JAX-WS 需要包装类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3708631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does JAX-WS need wrapper classes?
提问by Christian Strempfer
I created a simple webservice, which implements an add operation, and created some client files with wsimport. Now I want to include as less as possible wsdl specific artifacts. Here is an example of how the web service will be called:
我创建了一个简单的 web 服务,它实现了添加操作,并使用 wsimport 创建了一些客户端文件。现在我想包含尽可能少的 wsdl 特定工件。以下是如何调用 Web 服务的示例:
String serviceNamespace = "http://jws.samples.geronimo.apache.org/";
String serviceName = "CalculatorServiceService";
QName serviceQN = new QName(serviceNamespace, serviceName);
Service service = Service.create(new URL("http://localhost:8080/WebService/calculator?wsdl"), serviceQN);
String portNamespace = "http://jws.samples.geronimo.apache.org/";
String portName = "CalculatorServicePort";
QName portQN = new QName(portNamespace, portName);
Calculator myProxy = (Calculator) service.getPort(portQN, Calculator.class);
But it seems like I have to include wrapper classes for every message. For example the result message of the add operation:
但似乎我必须为每条消息都包含包装类。例如添加操作的结果消息:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "addResponse", propOrder = { "_return" })
public class AddResponse {
@XmlElement(name = "return")
protected int _return;
public int getReturn() {
return _return;
}
public void setReturn(int value) {
this._return = value;
}
}
These wrappers are used within annotations in the service interface:
这些包装器在服务接口的注解中使用:
@WebService(name = "Calculator", targetNamespace = "http://jws.samples.geronimo.apache.org/")
public interface Calculator {
@WebMethod
@RequestWrapper(className = "org.example.webservices.clients.dynamicproxy.Add")
@ResponseWrapper(className = "org.example.webservices.clients.dynamicproxy.AddResponse")
public int add(
@WebParam(name = "value1", targetNamespace = "")
int value1,
@WebParam(name = "value2", targetNamespace = "")
int value2);
}
If the annotations are removed, the web service won't run.
如果注释被删除,Web 服务将不会运行。
com.sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class org.example.webservices.clients.dynamicproxy.jaxws.Add is not found. Have you run APT to generate them?
com.sun.xml.ws.model.RuntimeModelerException:运行时建模器错误:未找到包装类 org.example.webservices.clients.dynamicproxy.jaxws.Add。你有没有运行 APT 来生成它们?
But why do I need those wrappers? Couldn't JAX-WS create those wrappers on-the-fly? Do you see any information, which couldn't be retrieved from the wsdl file?
但是为什么我需要这些包装器?JAX-WS 不能即时创建这些包装器吗?您是否看到了无法从 wsdl 文件中检索到的任何信息?
采纳答案by bmargulies
By default, your service is WRAPPED, not BARE, and so the top-level item in the message has to be a type with the same name as the operation. In 'classic' JAX-WS, this requires you to add a wrapper type.
默认情况下,您的服务是 WRAPPED,而不是 BARE,因此消息中的顶级项必须是与操作同名的类型。在“经典”JAX-WS 中,这需要您添加包装器类型。
If you use Apache CXF, it will automatically generate these wrappers with ASM.
如果您使用Apache CXF,它会使用 ASM 自动生成这些包装器。
回答by kaushik
In the service interface if you have an entry:
在服务界面中,如果您有一个条目:
@WebResult(targetNamespace = "http://jws.samples.geronimo.apache.org/")
before the addmethod in the Calculator interface, then you can get the wrapper classes created by the JAX-WS client on-the-fly using the following code:
在Calculator 接口中的add方法之前,您可以使用以下代码即时获取 JAX-WS 客户端创建的包装类:
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class TestWS{
public static void main(String args[]) throws Exception
{
URL url = "url to wsdl"
QName qname = new QName("http://jws.samples.geronimo.apache.org/", "Name of your service" );
Service service = Service.create(url, qname);
Calculator calcPort = service.getPort(Calculator.class);
System.out.println("Result of 1+2 is " + calcPort.add(1,2));
}
}

