barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

четверг, 19 марта 2015 г.

Birt: динамическая генерация SQL-запроса для отчета

Задача

Генерировать SQL-запрос, используемый для построения DataSet-а, динамически, в зависимости от значений параметров отчета.

Решение

Создаем DataSet, указываем у него пустой SQL. Идем в его advanced-свойства, находим там "Before open". Здесь можно писать произвольный JS-скрипт. Сгенерированный SQL необходимо записать в свойство this.queryText:

К параметрам отчета можно обращаться через params["myparam"].value. Если параметры отчета напрямую попадают в текст SQL, нужно не забыть их проэкранировать, чтобы избежать SQL-инъекций. В окне редактирования DataSet'а необходимо описать выходные колонки, которые будет выдавать сгенерированный скриптом SQL. Этот SQL может содержать параметры, тогда их нужно описать также, как это делается для статического SQL, в том же окне редактирования DataSet'а.

WSO2 ESB: MTOM-оптимизация и JMS

Задача

Складывать MTOM-оптимизированные SOAP-сообщения в JMS и читать их оттуда.

Решение

Во-первых, перед тем, как класть сообщение в JMS, включаем для него MTOM-оптимизацию (если она выключена глобально на сервере):
<property action="set" name="enableMTOM" scope="axis2"
                type="STRING" value="true"/>
Далее указываем axis2 на необходимость положить сообщение как бинарное, а не текстовое:
<property action="set" name="JMS_MESSAGE_TYPE" scope="axis2"
                type="STRING" value="JMS_BYTE_MESSAGE"/>
Указываем, что тип сообщения будет multipart/mixed:
<property action="set" name="messageType" scope="axis2"
                type="STRING" value="multipart/mixed"/>
Говорим, что content-type нужно положить в JMS-свойство ContentType (сохранение content-type требуется, т.к. в случае с multipart он будет содержать разделитель частей, необходимый для корректного чтения этого multipart'а):
<property action="set" name="transport.jms.ContentTypeProperty" scope="axis2"
                type="STRING" value="ContentType"/> 
Далее, в принимающей проксе прописываем, что content-type сообщения нужно брать из JMS-свойства ContentType:
    <parameter name="transport.jms.ContentType">
        <rules xmlns="http://ws.apache.org/ns/synapse">
                <jmsProperty>ContentType</jmsProperty>
        </rules>
    </parameter> 
В сценарии JMS -> JMS, когда MTOM-оптимизированное сообщение извлекается из JMS, обрабатывается, и снова кладется в JMS (опять оптимизированным), нужно перед помещением сообщения в исходящую очередь чистить этот самый транспортный заголовок ContentType:
            <property action="remove" name="ContentType" scope="transport"
                type="STRING"/> 
В противном случае WSO2 оставляет в исходящем сообщении тоже значение этого JMS-свойства, что и во входящем сообщении, при этом бинарное тело уже перекодировано с использованием другого MIME-разделителя, что приводит к ошибкам при последующем чтении MIME-а из JMS:
ERROR - JMSMessageReceiver Unknown error processing message
org.apache.axiom.om.OMException: Mime parts not found. Stream ended while searching for the boundary        at org.apache.axiom.attachments.Attachments.<init>(Attachments.java:238)
        at org.apache.axis2.builder.BuilderUtil.createAttachments(BuilderUtil.java:594)
        at org.apache.axis2.builder.BuilderUtil.createAttachmentsMap(BuilderUtil.java:545)
        ...

среда, 18 марта 2015 г.

birt: русские символы в значениях параметров отчета в JavaScript

Проблема

Есть birt-отчет, имеющий параметр, который используется в JavaScript-коде внутри отчета с помощью:
params["myparam1"].value
отчет развернут в веб-приложении birt на Tomcat, параметры в него передаются через GET. Проблема в том, что извлеченное в JavaScript значение параметра содержит некорректные значения для русских символов, как будто utf-8 строка прочиталась как cp1251.

Решение

Оборачиваем следующим образом:
decodeURIComponent(escape(params["component"].value))
Почему это работает, объяснено тут: http://ecmanaut.blogspot.ru/2006/07/encoding-decoding-utf8-in-javascript.html.