0

我正在努力阅读通过基于 SOAP 的 Web 服务传输的大文件。客户端代码因内存不足异常而失败。我正在使用 MTOM 发送二进制数据,希望能够处理传输和读取大文件。有问题的文件大小为 750mb。我正在使用 apache cxf。这是 Web 服务端点的实现。


@MTOM
@WebService(endpointInterface = "com.test.contentservice.service.IContentService")
@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class ContentServiceImpl implements IContentService {

@Override
    public ContentResponse getFile(ContentRequest req) {
        ContentResponse res = new ContentResponse();
        try {
            File file = this.contentManager.getFile(req);
            DataSource source = new FileDataSource(file);
            DataHandler dataHandler = new DataHandler(source);
            res.setFileData(dataHandler);
            res.setFileName(file.getName());
        } catch (Exception ex) {
        }
        return res;
    }

春季入学


<jaxws:endpoint id="contentService" implementor="#contentServiceImpl"
        address="/contentservice">
        <jaxws:dataBinding>
            <bean class="org.apache.cxf.jaxb.JAXBDataBinding">
                <property name="marshallerProperties">
                    <map>
                        <entry>
                            <key>
                                <value>jaxb.encoding</value>
                            </key>
                            <value>UTF-8</value>
                        </entry>
                    </map>
                </property>
            </bean>
        </jaxws:dataBinding>
        <jaxws:properties>
            <entry key="mtom-enabled" value="true" />
        </jaxws:properties>
    </jaxws:endpoint>

如您所见,“mtom-enabled”已打开。

客户端代码是使用 cxf wsdl2java 工具生成的。这是一个示例客户端代码


ContentResponse res =  new ContentResponse();
        try{
            res = getRegisterPort().getFile(req);
            DataHandler dataHandler = res.getFileData();
            if(dataHandler!=null){
                    final InputStream in = dataHandler.getInputStream(); 
                    byte[] bytes = IOUtils.toByteArray(in);
            }
        }catch (Exception ex) {
            LOGGER.error("Error in invoking getContent service",ex);
        }

这是响应对象


@XmlAccessorType( XmlAccessType.FIELD )
public class ContentResponse extends ContentServiceResponseBase {

    private String content;
    private String source;
    private String fileName;
    @XmlMimeType("application/octet-stream")
    private DataHandler fileData;
// Getter / Setter ...
}

我也在客户端代码级别设置 mtom

final BindingProvider bpAdmin = (BindingProvider) port;
        bpAdmin.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, curlUrl);
        SOAPBinding binding = (SOAPBinding)bpAdmin.getBinding();
        binding.setMTOMEnabled(true);

jvm入口如下:


java -Xms64m -Xmx6144m 

例外:

Exception in thread "taskExecutor-12" java.lang.OutOfMemoryError: Java heap space
       at java.util.Arrays.copyOf(Arrays.java:2882)
       at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
       at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:515)
       at java.lang.StringBuilder.append(StringBuilder.java:189)
       at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleCharacters(StAXStreamConnector.java:312)
       at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:176)
       at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:349)
       at com.sun.xml.internal.bind.v2.runtime.BridgeImpl.unmarshal(BridgeImpl.java:109)
       at com.sun.xml.internal.bind.api.Bridge.unmarshal(Bridge.java:222)
       at com.sun.xml.internal.ws.client.sei.ResponseBuilder$DocLit.readResponse(ResponseBuilder.java:514)
       at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:110)
       at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
       at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107)
       at $Proxy33.getFile(Unknown Source)

不确定我在这里缺少什么,任何指针都将受到高度赞赏。

  • 谢谢
4

1 回答 1

1

更新

在这种情况下,您可以在发送数据时尝试使用StreamingDataHandler ,并在服务器上调用readOnce吗?

您可以调整的参考,仅适用于流处理程序部分: http ://docs.oracle.com/cd/E14571_01/web.1111/e13734/mtom.htm


问题是否发生在IOUtils.toByteArray中?

如果不尝试缩小引发异常的操作并更新您的问题。

于 2013-06-19T02:09:31.230 回答