我正在使用CXF2.7.7构建一个WSDL优先的java Web服务,该服务使用MTOM。我的目的是能够通过这个Web服务上传大型(多GB)文件,下面是我的WSDL的一个片段
<!-- WSDL for MTOM service -->
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://objectstoreservice.example.com/" attributeFormDefault="unqualified"
elementFormDefault="unqualified" targetNamespace="http://objectstoreservice.example.com/">
<xs:element name="objectReqParam" type="tns:objectReqParam"/>
<xs:element name="objectRespParam" type="tns:objectRespParam"/>
<xs:complexType name="objectReqParam">
<xs:sequence>
<xs:element minOccurs="0" name="objName" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="1" name="ObjData"
type="xs:base64Binary" xmime:expectedContentTypes="application/octet-stream"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="objectRespParam">
<xs:sequence>
<xs:element minOccurs="0" name="respCode" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="objectUploadRequest">
<wsdl:part name="objectReqParam" element="tns:objectReqParam">
</wsdl:part>
</wsdl:message>
<wsdl:message name="objectUploadResponse">
<wsdl:part name="objectRespParam" element="tns:objectRespParam">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="ObjectStoreService">
<wsdl:operation name="uploadObject">
<wsdl:input name="objectUploadRequest" message="tns:objectUploadRequest"/>
<wsdl:output name="objectUploadResponse" message="tns:objectUploadResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ObjectStoreServiceServiceSoapBinding" type="tns:ObjectStoreService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="uploadObject">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="objectUploadRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="objectUploadResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ObjectStoreServiceService">
<wsdl:port name="ObjectStoreServicePort"
binding="tns:ObjectStoreServiceServiceSoapBinding">
<soap:address location="http://localhost:9090/ObjectStoreServicePort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我的意图是使用MTOM(从元素type=“xs:base64binary”xmime:expectedcontenttypes=“application/octet-stream中可以看出)通过该服务上载对象。
<beans xmlns="http://www.springframework.org/schema/beans"
... />
<jaxws:endpoint xmlns:objectstore="http://objectstoreservice.example.com/"
id="ObjectStoreServiceHTTP" address="http://localhost:9090/ObjectStoreServicePort"
serviceName="objectstore:ObjectStoreServiceService"
endpointName="objectstore:ObjectStoreServiceEndpoint"
implementor="com.example.objectstoreservice.server.ObjectStoreServiceImpl">
<jaxws:properties>
<!-- MTOM properties -->
<entry key="mtom-enabled" value="true"/>
<entry key="attachment-directory" value="/tmp/mtomattachments"/>
<entry key="attachment-memory-threshold" value="100000"/>
</jaxws:properties>
</jaxws:endpoint>
</beans>
类似地,我还配置了jax-ws客户机以使用MTOM,如下面的客户端spring配置文件所示
<beans xmlns="http://www.springframework.org/schema/beans ..../>
<jaxws:client id="objectStoreService"
serviceName="objectstore:ObjectStoreServiceService"
endpointName="objectstore:ObjectStoreServiceEndpoint"
address="http://localhost:9090/ObjectStoreServicePort"
serviceClass="com.example.objectstoreservice.ObjectStoreService">
<jaxws:properties>
<!-- MTOM properties -->
<entry key="mtom-enabled" value="true"/>
<entry key="attachment-memory-threshold" value="100000"/>
<entry key="attachment-directory" value="/tmp/mtomattachments"/>
<entry key="javax.xml.ws.client.connectionTimeout"
value="10000000" />
<entry key="javax.xml.ws.client.requestTimeout"
value="10000000" />
<jaxws:properties>
</jaxws:client>
下面我还包括了我的Java客户端代码的一个相关片段
/* --- Web-service client
*************************************************************************** */
package com.example.objectstoreservice.client;
import java.util.List;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;
import com.example.objectstoreservice.ObjectStoreService;
import com.example.objectstoreservice.ObjectReqParam;
import com.example.objectstoreservice.ObjectRespParam;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
public final class ObjectStoreServiceTester {
ObjectStoreService objectStoreService;
Binding binding ;
public ObjectStoreService getObjectStoreService() {
return objectStoreService;
}
// I haven't shown the code that sets the port object - objectStoreService
// Take my worrd for it - I have the right port object
public void setObjectStoreService(ObjectStoreService objectStoreService) {
this.objectStoreService = objectStoreService;
}
public void enableMTOM () {
binding = ((BindingProvider)objectStoreService).getBinding();
((SOAPBinding)binding).setMTOMEnabled(true);
}
public void testObjectStoreService()
{
enableMTOM();
System.out.println("Now uploading a data file to service");
ObjectReqParam objReqParam = new ObjectReqParam() ;
objReqParam.setObjName("File");
String fileName="C:/root/opt/files/ToSend.jpg";
FileDataSource inFileDataSource=new FileDataSource(fileName);
DataHandler dataHandler = new DataHandler(inFileDataSource);
System.out.println("Check content-type from dataHandler : " + dataHandler.getContentType());
System.out.println("Check obj signature from dataSource : " + dataHandler.getDataSource());
System.out.println("Check file-name from dataSource : " + dataHandler.getDataSource().getName());
objReqParam.setObjData(dataHandler);
System.out.println("Now uploading file:" + fileName);
objectStoreService.uploadObject(objReqParam);
System.out.println("Object upload successful");
}
}
MTOM: An exception occured while executing the Java class. null
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:217)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProje
ct(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProje
ct(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBu
ild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(Lifecycl
eStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Laun
cher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.jav
a:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(La
uncher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:
352)
Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occured
while executing the Java class. null
at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:346)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(Default
BuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:209)
... 19 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:291)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.OutOfMemoryError: Java heap space
at com.sun.xml.bind.v2.util.ByteArrayOutputStreamEx.readFrom(ByteArrayOu
tputStreamEx.java:75)
at com.sun.xml.bind.v2.runtime.unmarshaller.Base64Data.get(Base64Data.ja
va:196)
at com.sun.xml.bind.v2.runtime.unmarshaller.Base64Data.writeTo(Base64Dat
a.java:312)
at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.text(UTF8XmlOutput.j
ava:312)
at com.sun.xml.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.j
ava:356)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$PcdataImpl.
writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:183)
at com.sun.xml.bind.v2.runtime.MimeTypedTransducer.writeLeafElement(Mime
TypedTransducer.java:96)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTrans
ducedAccessorImpl.writeLeafElement(TransducedAccessor.java:256)
at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serial
izeBody(SingleElementLeafProperty.java:130)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBean
InfoImpl.java:361)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerialize
r.java:696)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serial
izeBody(SingleElementNodeProperty.java:158)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(Eleme
ntBeanInfoImpl.java:161)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(Eleme
ntBeanInfoImpl.java:131)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(Element
BeanInfoImpl.java:333)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(Element
BeanInfoImpl.java:340)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(Element
BeanInfoImpl.java:76)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.j
ava:494)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:
323)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.jav
a:251)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshal
lerImpl.java:95)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.writeObject(JAXBEncoderDecoder
.java:612)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.ja
va:240)
at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:169)
at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writePar
ts(AbstractOutDatabindingInterceptor.java:114)
at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutIn
terceptor.java:68)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseIntercept
orChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
这个问题是由于一些奇怪的原因导致与MTOM相关的spring配置没有被接收的结果--虽然我还不知道为什么--我可以通过编程方式将设置MTOM相关的属性添加到绑定类中来缓解这个问题--然后MTOM工作正常。不过,有一个警告--我暂时取消了https传输(我使用的是普通http传输)
// In My Web-service client code ....
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPBinding;
import com.sun.xml.ws.developer.JAXWSProperties;
// ... REST of my code
// After I create my Port - - did following for Enabling MTOM");
Binding binding = ((BindingProvider)port).getBinding();
if (binding == null) {
System.out.println("port .getBinding failed!!");
System.exit(-1);
}
((SOAPBinding) binding).setMTOMEnabled(true);
if (debugFlag)
System.out.println(" Port - setting chunking and other properties");
//Map contextMap=((BindingProvider)port).getRequestContext();
((BindingProvider)port).getRequestContext().put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE,32768);
((BindingProvider)port).getRequestContext().put(JAXWSProperties.MTOM_THRESHOLOD_VALUE,16000);
((BindingProvider)port).getRequestContext().put(JAXWSProperties.REQUEST_TIMEOUT,0);
((BindingProvider)port).getRequestContext().put(JAXWSProperties.CONNECT_TIMEOUT ,0);
可能没有多少开发人员像我一样面临这个问题<但是我想分享我已经解决了将近一个月的解决方案 我使用Kubernetes和docker compose,此Webflux服务(容器)设置了内存限制1g
我正在尝试编写一个RESTAPI,允许用户下载大文件(即 ContentCachingResponseWrapper中的默认flushBuffer()方法为空。如果我尝试调用copyBodyToResponse(),它用于将数据从缓存复制到流,它工作正常,但也会关闭流。这导致只向客户端发送第一块数据。 有什么建议吗? 我发现以下错误:
在Ubuntu中,当我运行hadoop示例时: 在日志中,我得到的错误为: 信息映射。JobClient:任务Id:尝试\u 201303251213\u 0012\u m\u000000 \u 2,状态:失败错误:Java堆空间13/03/25 15:03:43信息映射。JobClient:任务Id:trunt\u 201303251213\u 0012\u m\00000 1\u 2,状态:F
我在web服务器上使用apollo客户端与graphql服务器(也是apollo)通信。我有一个成功的查询,可以正常工作和检索数据,但当我尝试变异时,我会收到新的Apollo错误消息。复制/粘贴到graphiql中的相同突变非常有效。 我已经检查了graphql服务器上的CORS,它已启用并正常运行。我已经将代码中的变体复制并粘贴到graphiql编辑器中,它按预期工作。 有人能为我解释一下吗,或
我在做一个客户端/服务器应用程序。目前它的功能很好,但我需要添加一个“选项”。 server类如下所示: 因此许多客户端都能够连接到服务器。我的观点是:我希望一个连接的客户机(比如说,Client1)能够向他选择的另一个连接的客户机(Client2)发送一些东西。 我的问题是:Client1如何找到/拥有/检索Client2的套接字,因为所有的Client1都通过这个clientSocket在不同
我在Java开发了一个客户端-服务器游戏(称为“Set”)。 在调试过程中遇到了一个非常尴尬的问题: 如果在同一台机器上同时运行客户端和服务器(客户端连接到localhost),这个游戏工作得很棒(如果我运行服务器和大量客户端的话也是如此)。 但是,如果我在两台不同的机器上运行客户端和服务器,那么客户端和服务器都挂起了Inputstream readLine方法。 我会提到我正在使用writeBy