flex - ActionScript 3에서 "Null"(실제 성!)을 SOAP 웹 서비스에 전달하는 방법은 무엇입니까?




coldfusion wsdl (6)

추적

처음에 이것은 null 이 강제로 "null" 강제 변환되는 버그라고 생각하고 "null" == null 의 테스트가 통과했습니다. 그렇지 않습니다. 나는 가깝지만 아주 아주 잘못되었습니다. 미안합니다!

그 이후 로 wonderfl.net에 많은 재미mx.rpc.xml.* 의 코드를 추적했습니다. XMLEncoder 번째 줄의 XMLEncoder (3.5 소스에서), setValue 에서 모든 XMLEncoding은

currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));

그것은 본질적으로 다음과 같습니다 :

currentChild.appendChild("null");

원래 코드에 따라이 코드는 빈 XML 요소를 반환합니다. 하지만 왜?

원인

댓글 작성자 Justin Mclean에 따르면 버그 보고서 FLEX-33664 에 따르면 다음과 같은 원인이 있습니다 (이 사실을 확인하는 마지막 두 테스트 참조).

var thisIsNotNull:XML = <root>null</root>;
if(thisIsNotNull == null){
    // always branches here, as (thisIsNotNull == null) strangely returns true
    // despite the fact that thisIsNotNull is a valid instance of type XML
}

currentChild.appendChild 에 문자열 "null" 이 전달되면 먼저 "null" 이있는 루트 XML 요소로 변환 된 다음 해당 요소를 null 리터럴에 대해 테스트합니다. 이것은 약한 동등성 테스트이므로 null을 포함하는 XML이 null 유형으로 강제 변환되거나 null 유형이 "null"문자열을 포함하는 루트 xml 요소로 강제 변환되고 테스트가 실패해야하는 곳을 통과합니다. 한 가지 해결책은 "nullness"에 대해 XML을 검사 할 때 항상 엄격한 동등성 테스트를 사용하는 것입니다.

해결책

내가 생각할 수있는 유일한 합리적인 해결 방법은 ActionScript의 모든 버전에서이 버그를 수정하지 않고 "null"필드를 테스트 하여 CDATA 값 으로 이스케이프 처리하는 것입니다.

CDATA 값은 인코딩 / 디코딩 문제를 일으킬 수있는 전체 텍스트 값을 변경하는 가장 적절한 방법입니다. 예를 들어, 16 진 인코딩은 개별 문자를 의미합니다. CDATA 값은 요소의 전체 텍스트를 이스케이프 처리 할 때 선호됩니다. 가장 큰 이유는 인간의 가독성을 유지한다는 것입니다.

성이 Null 인 직원이 있습니다. 성을 검색 용어로 사용하면 직원 조회 응용 프로그램이 종료됩니다 (지금은 자주 발생합니다). 받은 오류 (Fiddler에게 감사드립니다!) :

<soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.MissingArgumentException : The SEARCHSTRING parameter to the getFacultyNames function is required but was not passed in.]</faultstring>

귀엽지? 응?

매개 변수 유형은 string 입니다.

나는 다음을 사용하고있다.

  • WSDL (SOAP)
  • 플렉스 3.5
  • ActionScript 3
  • ColdFusion 8

ColdFusion 페이지에서 객체로 webservice를 호출 할 때 오류 발생 하지 않습니다 .


@ doc_180은 숫자에 초점을 맞춘 것을 제외하고는 올바른 개념 이었지만 원래의 포스터에는 문자열 문제가있었습니다.

해결 방법은 mx.rpc.xml.XMLEncoder 파일을 변경하는 mx.rpc.xml.XMLEncoder 입니다. 이것은 라인 121입니다.

    if (content != null)
        result += content;

[나는 Flex 4.5.1 SDK를 보았다. 다른 버전에서는 줄 번호가 다를 수 있음]

기본적으로 유효성 검사는 실패합니다. 왜냐하면 'content is null'이고 당신의 인수가 발신 SOAP 패킷에 추가되지 않기 때문입니다. 따라서 누락 된 매개 변수 오류가 발생합니다.

유효성 검사를 제거하려면이 클래스를 확장해야합니다. 그런 다음 체인을 따라 큰 눈덩이가 생기고 SOAPEncoder가 수정 된 XMLEncoder를 사용하도록 수정 한 다음 수정 된 SOAPEncoder를 사용하도록 Operation을 수정 한 다음 WebService를 사용하여 대체 Operation 클래스를 사용합니다.

나는 그것에 몇 시간을 보냈지 만, 계속 나아갈 필요가있다. 아마도 하루 이틀이 걸릴 것입니다.

XMLEncoder 라인을 수정하고 자신의 클래스를 사용하기 위해 원숭이 패치를 할 수 있습니다.

또한 ColdFusion과 함께 RemoteObject / AMF를 사용하도록 전환하면 null이 문제없이 전달됩니다.

2011 년 11 월 16 일 업데이트 :

RemoteObject / AMF에 대한 마지막 코멘트에 최근에 추가 된 내용이 있습니다. CF10을 사용하는 경우; 오브젝트의 널 값을 갖는 특성은 서버 측 오브젝트에서 제거됩니다. 따라서 액세스하기 전에 속성 존재 여부를 확인해야합니다. 그렇지 않으면 런타임 오류가 발생합니다. 다음과 같이 확인하십시오.

<cfif (structKeyExists(arguments.myObject,'propertyName')>
 <!--- no property code --->
<cfelse>
 <!--- handle property  normally --->
</cfif>

이것은 CF9에서의 행동 변화입니다. null 프로퍼티는 하늘의 캐릭터 라인이됩니다.

2014 년 12 월 6 일 편집

null이 처리되는 방법에 대한 질문이 있기 때문에 문자열 "null"이 예약어 null과 어떻게 관련되는지 보여주는 간단한 샘플 응용 프로그램이 여기에 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            protected function application1_initializeHandler(event:FlexEvent):void
            {
                var s :String = "null";
                if(s != null){
                    trace('null string is not equal to null reserved word using the != condition');
                } else {
                    trace('null string is equal to null reserved word using the != condition');
                }

                if(s == null){
                    trace('null string is equal to null reserved word using the == condition');
                } else {
                    trace('null string is not equal to null reserved word using the == condition');
                }

                if(s === null){
                    trace('null string is equal to null reserved word using the === condition');
                } else {
                    trace('null string is not equal to null reserved word using the === condition');
                }

            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:Application>

추적 출력은 다음과 같습니다.

null 문자열이! = 조건을 사용하여 null 예약어와 같지 않습니다.

null 문자열이 == 조건을 사용하여 null 예약어와 같지 않습니다.

null 문자열이 === 조건을 사용하여 null 예약어와 같지 않습니다.


그것은 kludge입니다. 그러나 SEARCHSTRING 의 최소 ​​길이 (예 : 2 자)가 있다고 가정하고 SEARCHSTRING 매개 변수를 두 번째 문자에서 substringSEARCHSTRING 다음 SEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). 대신 두 개의 매개 변수로 전달하십시오 SEARCHSTRING2 ("ll"). 데이터베이스에 쿼리를 실행할 때 다시 Concatenate 하십시오.


글쎄, 난 플렉스 'SOAP 인코더의 구현을 null 값을 잘못 serialize하는 것으로 보인다. 문자열 널로 직렬화하는 것은 좋은 해결책이 아닌 것 같습니다. 공식적으로 올바른 버전은 null 값을 다음과 같이 전달하는 것 같습니다.

<childtag2 xsi:nil="true" />

따라서 "Null"의 값은 유효한 문자열이 아닌 다른 문자열 일 것입니다.

아파치 플렉스에서이 문제를 해결하는 것이 어렵지는 않을 것이라고 생각한다. Jira 문제를 열거 나 apache-flex 메일 링리스트에 연락하는 것이 좋습니다. 그러나 이것은 클라이언트 쪽만 고칠 것입니다. ColdFusion이 이러한 방식으로 인코딩 된 null 값으로 작업 할 수 있는지 말할 수 없습니다.

Radu Cotescu의 블로그 게시물 soapUI 요청에 null 값을 보내는 방법을 참조하십시오.


해킹으로 'Null'문자열을 절대로 발생하지 않을 것으로 예를 들어 XXNULLXX로 변환하고 서버에서 다시 변환하여 클라이언트 측에서 특별한 처리를 고려할 수 있습니다.

그것은 꽤 아니지만 그런 경계 사건에 대한 문제를 해결할 수 있습니다.


ActionScript 에서 null 값을 문자열로 지정하면 "NULL" 문자열이 반환됩니다. 내의 의혹은 누군가가 문자열 "NULL"null 로 디코딩하여 여기에 표시된 파손을 일으키는 것이 좋습니다. 이는 아마도 null 객체를 전달하고 데이터베이스에서 문자열을 가져 오는 것이므로 그들은 그것을 원하지 않았다. (그런 종류의 버그도 확인해야한다.)