SOAP 기반 웹 서비스를 통해 전송 된 대용량 파일을 읽으려고합니다. 메모리 부족 예외로 인해 클라이언트 코드가 실패합니다. MTOM을 사용하여 이진 데이터를 보내고 큰 파일을 전송하고 읽을 수 있기를 바랍니다. 문제의 파일 크기는 750MB입니다. 나는 아파치 cxf를 사용하고있다. 다음은 웹 서비스 엔드 포인트 implentation입니다.SOAP 웹 서비스를 사용하여 대용량 파일을 검색하는 동안 메모리 부족 예외가 발생했습니다.
<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
@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;
}
봄 항목은, "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)
확인 내가 여기에 누락 무엇을, 어떤 포인터가 높게 평가되는 것은 아닙니다.
- 감사
JVM에서 JVM 옵션을 선택하셨습니까? – WeMakeSoftware
@Funtik .. "ps -ef"는 올바른 jvm 매개 변수를 보여줍니다. – Shamik