Веб-сервис Coldfusion используется в качестве WSDL-удушающих управляющих символов - PullRequest
1 голос
/ 10 марта 2011

Клиенты загружают файлы в формате .doc в каталог сервера, и текст в них извлекается с использованием POI согласно записи Рэя Камдена здесь Содержимое сохраняется в поле text / memo в базе данных MySQL.и сделан доступным как веб-сервис, который используется как wsdl.Все работает, как предполагалось, до тех пор, пока потребители веб-службы не получат доступ к записям, содержащим определенные (я полагаю) контрольные символы, и в этот момент веб-служба выдает ошибку 500.

В базе данных проблемных строк, кажется, имеются контрольные символы, и когда текстовое поле отображается в Firefox, появляются и странные символы.enter image description here Веб-служба просто возвращает запрос CF returntype = "any" и называется

<cfinvoke webservice="https://nww.someplace.nhs.uk/cfcs/providerapi.cfc?wsdl" 
method="getPendingReferrals" returnvariable="getReferrals">
    <cfinvokeargument name="userName" value=#username#>
    <cfinvokeargument name="password" value=#password#>
    <cfinvokeargument name="maxrows" value=#maxrows#>
</cfinvoke>

Я предполагаю, что WSDL не может передавать эти символы, поэтому есть ли способ кодировать их или сделатьЯ просто должен удалить их с помощью регулярных выражений или что-то?

<cfcomponent>
    <cffunction  output="false" access="remote"  returntype="any" name="getPendingReferrals">
        <cfargument required="false" name="userName" type="string"/>
        <cfargument required="false" name="password" type="string"/>
        <cfargument required="false" name="maxrows" type="numeric" default="20"/>       
        <cfset var q="">

<cfinvoke component="cfcs.security" method="checkAuthenticated" returnvariable="checkAuth">
    <cfinvokeargument name="username" value="#arguments.userName#">
    <cfinvokeargument name="password" value="#arguments.password#">
</cfinvoke>


<cfif checkAuth.authenticates is "true"> 
    <!--- log the login --->
    <cfset filename=#datepart("yyyy", now())#&#datepart("m", now())#&#datepart("d", now())#&"loginlog.txt">
    <CFSET OUTFILE = "#application.Root#"&"logs\"&"#filename#">
    <cfif #FileExists(OUTFILE)# is "Yes">
        <cffile action="append" file="#OUTFILE#"  output="#checkAuth.userName#, #now()#,  #remote_addr#, #Left(http_user_agent, 50)#">
    <cfelse>
        <CFFILE action="write" output="#checkAuth.userName#, #now()#,  #remote_addr#, #Left(http_user_agent, 50)#" file="#OUTFILE#">
    </cfif> 


        <cfif checkAuth.organisationID is 1>
            <cfset toStr="toID=1">
        <cfelseif checkAuth.organisationID is 28>
            <cfset toStr="(toID=28 OR toID=29)">
        </cfif>

        <cfquery name="q" datasource='mySqlData' maxrows=#arguments.maxrows#>
            SELECT messages.messageID, messages.toID, messages.fromID AS referrerID, (SELECT CONCAT(title, ' ',firstName, ' ', lastname) FROM users WHERE users.userID = messages.fromID) as referrerName,messages.threadID, messages.messageBody, messages.dateCreated, messages.dateSent, 
            messages.deleted, messages.createdByID, (SELECT CONCAT(title, ' ',firstName, ' ', lastname) FROM users WHERE users.userID = messages.createdByID) as createdByName, (SELECT organisationName FROM organisations WHERE messages.originatingOrganisationID = organisations.organisationID) as originatingOrganisationName, messages.originatingOrganisationID, messages.viewed, messages.referral, messages.actioned, messages.patientID, messages.refTypeID, messages.specialtyID, organisations.organisationName AS toOrganisationName, patients.nhsNumber AS patientNHSnumber, patients.patientTitle, patients.patientLastname, patients.patientFirstname,  patients.patientDOB, patients.address1 as patientAddress1, patients.address2 AS patientAddress2, patients.address3 AS patientAddress3, patients.address4 AS patientAddress4, patients.postcode AS patientPostcode, patients.patientPhone1
            FROM users INNER JOIN (organisations INNER JOIN (patients INNER JOIN messages ON patients.patientID = messages.patientID) ON organisations.organisationID = messages.toID) ON users.userID = messages.fromID 
            WHERE #toStr#
            AND NOT actioned
            AND NOT originatingOrganisationID=3
            ORDER BY messageID
            </cfquery>


            <cfif isQuery(q)>
                <cfreturn q>
            <cfelse>
                <cfreturn "Error : in query">
            </cfif>



<cfelse> 
    <cfreturn "Error : failed to authenticate">
</cfif>    

</cffunction>

Ответы [ 3 ]

2 голосов
/ 11 марта 2011

Вы, вероятно, должны удалить все символы с высоким ascii, используя регулярное выражение. Одним из лучших, которые я нашел, была , написанная Беном Наделем, здесь . (Хотя он не был идеальным, и я сделал некоторые улучшения в комментариях .)

По сути, если вы просто хотите удалить символы высокого ascii, сделайте следующее:

<cfset result = reReplace(messageBody, "[^\x20-\x7E\x0D\x09]", "", "all") />

В этом регулярном выражении используется метод белого списка, позволяющий сохранять только печатаемые символы:

  • \x20-\x7E = {пробел}! "# $% & '() * +, -. / 0-9:; <=>? @ A-Z [\] ^ _` a-z {|} ~
  • \x0D = возврат каретки
  • \x09 = горизонтальная табуляция

Если вам нравится этот подход к очистке, вы можете использовать метод Шона Койна для обновления запроса с помощью цикла:

<cfloop query="q">
    <cfset querySetCell(
        q,
        "messageBody",
        clean(q.messageBody[q.currentRow]),
        q.currentRow
    )/>
</cfloop>
<cffunction name="clean">
    <cfargument name="in" />
    <cfreturn reReplace(arguments.in, "[^\x20-\x7E\x0D\x09]", "", "all") />
</cffunction>
1 голос
/ 11 марта 2011

Это не идеально, но вы можете попробовать что-то вроде:

<cfloop query="q">
    <cfset querySetCell(q,"messageBody",xmlFormat(q.messageBody[q.currentRow]),q.currentRow) />
</cfloop>

Если xmlFormat не удаляет все символы (известно, что они пропустили несколько символов), вам может потребоваться написать ручной метод для их удаления.

0 голосов
/ 10 марта 2011

Как упоминает Шон, вам нужно избегать всевозможных специальных символов, чтобы получить действительный XML - взгляните на http://www.petefreitag.com/item/202.cfm, например

...