2012-12-08 4 views
1

SOAP 호출에서받은 이진 데이터를 읽으려고 STAX 이벤트 API를 사용 중이며이를 소비자에게 스트리밍하려고합니다. 는 SOAP 호출에서 XML 페이로드는 다음과 같이이다 :STAX API 읽기 이진 데이터

......... 
    <BinaryObject mimeCode="text/xml">PHNvYXAtZW52OkVudmVsb3BlIHhtbG5zOnNvYXAtZW52PSJodHRwOi8vc 
     2NoZW1hcy54bWxzb2FwLhm9yZy9zb2FwL2VudmVsb3BlLyI+DQogICA8c29hcC1lbnY6SGVhZGVy 
     Lz4NCiAgIDxzb2FwLWVudjpCb2R5Pg0KICAgICAgPG5tOkF0dGFjaG1lbnRGb2xkZXJEb2N1bWVudE 
     ZpbGVDb250ZW50QnlJRFJlc3BvbnNlX3N5bmMgeG1sbnM6bm09Imh0dHA6Ly9zYXAuY29tL3hpL1NB 
     UEdsb2JhbDIwL0dsb2JhbCIgeG1sbnM6cHJ4PSJ1cm46c2FwLmNvbTpwcm94eTpISlc6LzFTQUkvVE 
     FTMEIzNDE4MTJBNTc5MDUyM0I5RTU6ODA0Ij4NCiAgICAgICAgIDxBdHRhY..... </BinaryObject> 

XMLInputFactory inputFactory = XMLInputFactory.newInstance(); 
    inputFactory.setProperty(XMLInputFactory.IS_COALESCING, true); 

    InputStream in; 

    try { 

     in = new ByteArrayInputStream(response.getBytes()); 

     XMLEventReader eventReader; 
     eventReader = inputFactory.createXMLEventReader(in); 

     while (eventReader.hasNext()) { 
      XMLEvent event = eventReader.nextEvent(); 

      // Start element 
      if (event.isStartElement()) { 
       StartElement startElement = event.asStartElement(); 

       if (startElement.getName().getLocalPart().toString() 
         .equals("BinaryObject")) { 

        Iterator<Attribute> attributes = startElement 
          .getAttributes(); 

        while (attributes.hasNext()) { 
         Attribute attribute = attributes.next(); 

         if (attribute.getName().toString() 
           .equals("mimeCode")) { 
          mimeType = attribute.getValue(); 
         } 
        } 

        event = eventReader.peek(); 

        if (event.isCharacters()) { 
         event = eventReader.nextEvent(); 
         content = event.asCharacters().getData(); 
        } 
       } 
      } 
     } 

    } catch (XMLStreamException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    m_servletResponse.setContentType(mimeType); 
     m_servletResponse.getWriter().print(javax.xml.bind.DatatypeConverter 
       .printBase64Binary(content.getBytes())); 

이 코드 여러 문제가있다 내가 구문 분석에 사용하는 자바 코드를 다음과 소비자에게 데이터를 전송 : 큰 파일의 경우

  1. (> 1 인 메가 바이트) 나는 StackOverflow의 오류를 얻을

  2. 작은 파일의 경우에도 png 파일을 시도 할 때 파일이 유효하지 않음 (소비자) 오류가 발생합니다.

어떻게 이러한 문제를 극복 할 수 있습니까?

추 신 : STAX를 처음 사용하고 있습니다!

==================== 편집 : =================== = **

아래 Evgeniy의 제안을 바탕으로 이제는 작은 파일 (예 : PNG)을 처리 할 수있게되었습니다. 그러나 대용량 PDF 문서> 1 메가 바이트 나는 아래 오류가 발생합니다. 여기에 무엇이 잘못 될지에 대한 아이디어가 있습니까?

2012 12 09 06 : 50 : 19 # + 00 # ERROR # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # 스레드의 예외 " http-bio-8041-exec-9 "| 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # seodportal # 웹 # null # null # java.lang.StackOverflowError | 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # com.sun.org. apache.xerces.internal.impl.XMLScanner.isInvalid (XMLScanner.java:1334) | 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # com.sun.org. apache.xerces.internal.impl.XMLScanner.scanCharReferenceValue (XMLScanner.java:1294) | 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # com.sun.org. (XMLDocumentFragmentScannerImpl.java:3024) | 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # com.sun.org. (XMLDocumentFragmentScannerImpl.java:2919) | 2012 12 09 06 : 50 : 19 # + 00 # 오류 # System.err ## 익명 # http-bio-8041-exec-9 ## seodportal # web # null # null # com.sun.org. (XMLDocumentFragmentScannerImpl.java:3059) |

답변

1

우선 XMLStreamReader는 특수 용도로 설계되었으며 대신 XMLStreamReader를 사용합니다. 여기 실시 예의 또한 상기 접근

 XMLInputFactory inputFactory = XMLInputFactory.newInstance(); 
     inputFactory.setProperty(XMLInputFactory.IS_COALESCING, true); 
     InputStream in = new ByteArrayInputStream(response.getBytes()); 
     XMLStreamReader xr = inputFactory.createXMLStreamReader(in); 
     while (xr.hasNext()) { 
      int next = xr.next(); 
      if (next == XMLStreamConstants.START_ELEMENT) { 
       if (xr.getLocalName().equals("BinaryObject")) { 
        String mimeCode = xr.getAttributeValue(null, "mimeCode"); 
        if (mimeCode.equals("text/xml")) { 
         xr.next(); 
        // for efficiency we can access xr inner buffer chars directly 
        char[] b = xr.getTextCharacters(); 
        int textStart = xr.getTextStart(); 
        int textLength = xr.getTextLength(); 
        // or simply get it as String 
        String text = xr.getText(); 
        // in this example I will use JDK's internal decoder com.sun.org.apache.xerces.internal.impl.dv.util.Base64      
        byte[] bytes = new Base64().decode(text); 

        } 
       } 
      } 
     } 
+0

이며, 모두 BinaryObject는 MIME 타입 이미지/PNG의 경우 문제는 즉 남아 다운로드 화상 유효 (행해질 Base64 인코딩 λ)는 아니다. 1MB가 넘는 큰 파일의 경우 StackOverflow 문제가 발생합니다. – mithrandir

+0

예를 들어 디코더가 추가 된 SOE - 스택 추적 추가 질문 –

+0

감사합니다. – mithrandir