【问题标题】:XSL:FO to PDF Mediator fails in "no object DCH for MIME type application/pdf"已解决:XSL:FO 到 PDF 调解器在“MIME 类型应用程序/pdf 的无对象 DCH”中失败
【发布时间】:2021-12-17 18:47:03
【问题描述】:

我已经编写了一个简单的 XSL:FO 到 PDF 中介器。 XSL:FO 文档的转换似乎成功,但返回 PDF 似乎不起作用。

在axis2.xml文件中我添加了application/pdf的规则:

<messageFormatter contentType="application/pdf" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>   
<messageBuilder contentType="application/pdf" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>

错误信息:

org.apache.axiom.om.OMException: Error reading data handler
        at org.apache.axiom.om.impl.llom.OMTextImpl.internalSerialize(OMTextImpl.java:455)
        at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:555)
        at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:879)
        at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:230)
        at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:125)
        at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:113)
        at org.apache.axiom.om.impl.llom.OMElementImpl.toString(OMElementImpl.java:992)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuffer.append(StringBuffer.java:263)
        at org.apache.synapse.mediators.builtin.LogMediator.getFullLogMessage(LogMediator.java:208)
        at org.apache.synapse.mediators.builtin.LogMediator.getLogMessage(LogMediator.java:139)
        at org.apache.synapse.mediators.builtin.LogMediator.mediate(LogMediator.java:102)
        at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:109)
        at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:71)
        at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
        at org.apache.synapse.mediators.MediatorFaultHandler.onFault(MediatorFaultHandler.java:96)
        at org.apache.synapse.FaultHandler.handleFault(FaultHandler.java:101)
        at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:253)
        at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
        at org.apache.synapse.transport.passthru.ServerWorker.processEntityEnclosingRequest(ServerWorker.java:415)
        at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:152)
        at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/pdf
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:896)
        at javax.activation.DataHandler.writeTo(DataHandler.java:317)
        at org.apache.axiom.util.stax.XMLStreamWriterUtils.writeBase64(XMLStreamWriterUtils.java:62)
        at org.apache.axiom.util.stax.XMLStreamWriterUtils.writeDataHandler(XMLStreamWriterUtils.java:138)
        at org.apache.axiom.om.impl.llom.OMTextImpl.internalSerialize(OMTextImpl.java:452)

中介代码目前是:

public class PDFMediator extends AbstractMediator {

    public boolean mediate(MessageContext context) {
        trace.info(new String("PdfMediator Process Started"));

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            OMElement body = context.getEnvelope().getBody();
            String text = body.getFirstElement().toString();
            Source src = new StreamSource(new StringReader(text));

            final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();

            Result res = new SAXResult(fop.getDefaultHandler());
            transformer.transform(src, res);
            trace.info("PDF: " + out.toString());

            DataHandler dataHandler = new DataHandler(out, MimeConstants.MIME_PDF);
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMText textData = fac.createOMText(dataHandler, true);
            body.addChild(textData);

            context.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);
            context.setProperty(Constants.Configuration.MESSAGE_TYPE, MimeConstants.MIME_PDF);
            context.setProperty(Constants.Configuration.CONTENT_TYPE, MimeConstants.MIME_PDF);
            context.setProperty(org.apache.axis2.Constants.Configuration.CONTENT_TYPE, MimeConstants.MIME_PDF);
            Object o = context.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
            Map<String, String> headers = (Map<String, String>) o;
            if (headers != null) {
                headers.remove(HTTP.CONTENT_TYPE);
                headers.put(HTTP.CONTENT_TYPE, MimeConstants.MIME_PDF);
            }

            trace.info(new String("PdfMediator Process Finished successfully"));
        } catch (FOPException e) {
            trace.error(new String("PdfMediator Process Failed (FOP): ")+e.toString());
            e.printStackTrace();
            context.setProperty(NhttpConstants.HTTP_SC, 500);
            context.setProperty(NhttpConstants.ERROR_DETAIL, "XSL:FO to PDF transformation failed");
            context.setProperty(NhttpConstants.ERROR_MESSAGE, "XSL:FO to PDF transformation failed: "+e.toString());
            handleException("XSL:FO to PDF transformation failed (FOP): "+e.toString(), context);
        } catch (TransformerException e) {
            trace.error(new String("PdfMediator Process Failed (transform): ")+e.toString());
            e.printStackTrace();
            context.setProperty(NhttpConstants.HTTP_SC, 500);
            context.setProperty(NhttpConstants.ERROR_DETAIL, "XSL:FO to PDF transformation failed");
            context.setProperty(NhttpConstants.ERROR_MESSAGE, "XSL:FO to PDF transformation failed: "+e.toString());
            handleException("XSL:FO to PDF transformation failed (transform): "+e.toString(), context);
        } finally {
            // Clean-up
            try {
                out.close();
            } catch (IOException e) {
                trace.error(new String("PdfMediator Process Failed"));
                handleException("IOError: "+e.toString(), context);
                e.printStackTrace();
            }
        }
        return true;
    }
}

'trace.info("PDF:" + out.toString());'使用正确的 PDF 打印。 'trace.info(new String("PdfMediator Process Finished successfully"));'也是如此

用于测试的文档是:

<?xml version="1.1" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master master-name="my_page" margin="0.5in">
   <fo:region-body/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="my_page">
  <fo:flow flow-name="xsl-region-body">
   <fo:block>Hello world!</fo:block>
  </fo:flow>
 </fo:page-sequence>
</fo:root>

WSO2 中的代理如下:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="PDFTest"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <log level="custom">
            <property expression="/" name="input"/>
         </log>
         <class name="com.example.PDFMediator"/>
         <log level="custom">
            <property expression="/" name="output"/>
         </log>
         <send/>
      </inSequence>
   </target>
   <description/>
</proxy>

【问题讨论】:

  • 很高兴,您已修复它,但请更喜欢“发布答案”,而不是更新(问题)“已解决”! :-)

标签: wso2 wso2esb xsl-fo synapse


【解决方案1】:

解决方案是使用SynapseBinaryDataSource,这将使用正确的翻译。唯一剩下的问题是输出不是PDF,因此调用代理需要添加消息类型。

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="PDFTest"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <class name="com.example.PDFMediator"/>
         <loopback/>
      </inSequence>
      <outSequence>
         <property name="messageType"
                   scope="axis2"
                   type="STRING"
                   value="application/pdf"/>
         <respond/>
      </outSequence>
   </target>
   <description/>
</proxy>
public class PDFMediator extends AbstractMediator {

    private static final Log log = LogFactory.getLog(PDFMediator.class);

    private ByteArrayOutputStream convertToPdf(MessageContext context, String text) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            Source src = new StreamSource(new StringReader(text));

            final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();

            Result res = new SAXResult(fop.getDefaultHandler());
            transformer.transform(src, res);
        } catch (FOPException e) {
            log.error(new String("PdfMediator Process Failed (FOP): ") + e.toString());
            handleException("XSL:FO to PDF transformation failed (FOP): " + e.toString(), context);
        } catch (TransformerException e) {
            log.error(new String("PdfMediator Process Failed (transform): ") + e.toString());
            handleException("XSL:FO to PDF transformation failed (transform): " + e.toString(), context);
        }
        return out;
    }

    private void replaceBody(MessageContext context, ByteArrayInputStream data) throws IOException {
        OMFactory factory = OMAbstractFactory.getOMFactory();
        OMNamespace ns = factory.createOMNamespace("http://ws.apache.org/commons/ns/payload", "ns");
        OMElement element = factory.createOMElement("binary", ns);

        DataHandler dataHandler = new DataHandler(
            new SynapseBinaryDataSource(data, MimeConstants.MIME_PDF));
        OMText textData = factory.createOMText(dataHandler, true);
        textData.setBinary(true);
        element.addChild(textData);

        // remove all child elements
        for (Iterator itr = context.getEnvelope().getBody().getChildElements(); itr.hasNext(); ) {
            OMElement child = (OMElement) itr.next();
            child.detach();
        }
        // add current node
        context.getEnvelope().getBody().addChild(element);

        // set message context properties
        context.setProperty(Constants.Configuration.MESSAGE_TYPE, MimeConstants.MIME_PDF);
        context.setProperty(Constants.Configuration.CONTENT_TYPE, MimeConstants.MIME_PDF);
        Object o = context.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        Map<String, String> headers = (Map<String, String>) o;
        if (headers != null) {
            headers.remove(HTTP.CONTENT_TYPE);
            headers.put(HTTP.CONTENT_TYPE, MimeConstants.MIME_PDF);
        }
    }

    public boolean mediate(MessageContext context) {
        log.info("PdfMediator Process Started");

        ByteArrayOutputStream out;
        try {
            OMElement body = context.getEnvelope().getBody();
            String text = body.getFirstElement().toString();

            out = convertToPdf(context, text);
            replaceBody(context, new ByteArrayInputStream(out.toByteArray()));

            log.info("PdfMediator Process Finished successfully");
            out.close();
        } catch (IOException e) {
            log.error(new String("PdfMediator Process Failed"));
            handleException("IOError: " + e.toString(), context);
            e.printStackTrace();
        }
        return true;
    }
}

【讨论】:

    猜你喜欢
    • 2015-01-06
    • 2016-02-29
    • 2014-10-16
    • 2016-01-11
    • 2011-09-13
    • 2019-07-21
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多