2013-06-18 59 views
0

我正在努力閱讀通過基於SOAP的Web服務傳輸的大文件。客戶端代碼失敗,出現內存不足異常。我使用MTOM發送二進制數據,希望能夠照顧傳輸和讀取大文件。有問題的文件大小是750MB。我使用的是Apache cxf。以下是Web服務端點實現。使用SOAP webservice檢索大文件時出現內存不足異常


@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-」 已開啓。

客戶端代碼是使用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) 

不知道我很想念這裏,任何指針將高度讚賞。

  • 感謝
+0

是否確定JVM選項是由JVM選取的? – WeMakeSoftware

+0

@Funtik ..「ps -ef」顯示正確的jvm參數 – Shamik

回答

0

UPDATE

能發送數據時,通過調用readOnce在服務器上您嘗試在這種情況下StreamingDataHandler

參考,你可以適應,只是流處理器部分: http://docs.oracle.com/cd/E14571_01/web.1111/e13734/mtom.htm


是在IOUtils.toByteArray出現的問題?

如果不嘗試縮小拋出異常的操作並更新您的問題。

+0

它甚至沒有達到如果(dataHandler!= null)最終的InputStream in = dataHandler.getInputStream(); byte [] bytes = IOUtils.toByteArray(in);內存不足異常發生在DataHandler dataHandler = res.getFileData(); – Shamik

+0

我正在使用apache cxf.My的理解是CXF只是直接支持流式傳輸而不需要特殊的StreamingDataHandler。 StreamingDataHandler適用於JAX-WS。 – Shamik

相關問題