3

我有一个使用 EJB3 的 JBoss Web 服务 (5.1) 在我们的 MSSQL 服务器上运行用于 dao 更新/插入的应用程序。

应用程序设置的一部分包括一个自定义 SOAPHandler,它用于从 ByteArray[Output/Input]Stream 中的消息中解析 xml 并将其打印到服务器日志中。

这在大多数情况下都可以正常工作,但最近我们接手了一个正在发送大量数据的新客户,并且由于预算很少(实际上不存在),我必须在旧电脑上运行我们的测试/集成服务(相信我,我不想)。

果然,没多久我就遇到了:

    2012-11-21 14:20:40,128 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]. *removed* -5) Servlet.service() for servlet *MyIface* threw exception
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.write(UTF8XmlOutput.java:394)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.write(UTF8XmlOutput.java:386)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.endTag(UTF8XmlOutput.java:273)
    at com.sun.xml.bind.v2.runtime.output.NamespaceContextImpl$Element.endElement(NamespaceContextImpl.java:493)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.endElement(XMLSerializer.java:310)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)

有人可以在这里给我一些关于分块解析的提示吗?我已经在其他线程中检查过这个线程,我的问题听起来与此类似,但我不知道要使用哪种 api/方法。

这是我的处理程序:

@SuppressWarnings("rawtypes")
public class MyHandler extends GenericSOAPHandler {

    private void print(InputStream input, OutputStream out) throws Exception {
        try {
            DocumentBuilder parser;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newDocumentBuilder();
            Document document = parser.parse(input);
            Transformer serializer = TransformerFactory.newInstance().newTransformer();
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            serializer.transform(new DOMSource(document), new StreamResult(out));
        } catch (TransformerException e) {
            // A fatal error occurred
            throw new Exception(e);
        }
    }


    @Override
    protected boolean handleInbound(MessageContext msgContext) {
        SOAPMessageContext soapMessageCtx = (SOAPMessageContext) msgContext;
        SOAPMessage soapMessage = soapMessageCtx.getMessage();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            soapMessage.writeTo(outputStream);
            byte[] array = outputStream.toByteArray();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(array);
            System.out.println("SOAP request message:\n");
            print(inputStream, System.out);
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    protected boolean handleOutbound(MessageContext msgContext) {
        SOAPMessageContext soapMessageCtx = (SOAPMessageContext) msgContext;
        SOAPMessage soapMessage = soapMessageCtx.getMessage();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            soapMessage.writeTo(outputStream);
            byte[] array = outputStream.toByteArray();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(array);
            System.out.println("SOAP response message:\n");
            print(inputStream, System.out);
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

}

谢谢

4

0 回答 0