Cách vượt qua Null ăn (tên thật!) Cho dịch vụ web SOAP trong ActionScript 3


4636

Chúng tôi có một nhân viên có họ là Null. Ứng dụng tra cứu nhân viên của chúng tôi bị giết khi tên cuối cùng được sử dụng làm thuật ngữ tìm kiếm (điều này xảy ra khá thường xuyên bây giờ). Lỗi nhận được (cảm ơn Fiddler!) Là:

<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>

Dễ thương hả?

Loại tham số là string.

Tôi đang dùng:

  • WSDL ( SOAP )
  • Flex 3.5
  • ActionScript 3
  • ColdFusion 8

Lưu ý rằng lỗi không xảy ra khi gọi dịch vụ web là một đối tượng từ trang ColdFusion.


6
Nó có thể không giúp bạn nhiều cho vấn đề cụ thể, nhưng SOAP 1.2 cho phép các giá trị không thể, xem w3.org/TR/2001/WD-soap12-20010709/#_Toc478383513
JensG

6
Tôi có cảm giác nó liên quan đến Dave Null.
George Gibson

2
Ít nhất nó không liên quan đến Chuck Norris. Đây là lý do để tránh xa anh ấy trong mã: Codequeeze.com/
SDsolar

42
Có nhân viên đã xem xét để thay đổi tên của mình?
Tatranskymvedved

11
Anh ta thực sự nên xem xét việc mua một con chó Con trỏ và gọi anh ta là NullPulum.
Antonio Alvarez

Câu trả lời:


1109

Theo dõi nó xuống

Lúc đầu, tôi nghĩ rằng đây là một lỗi cưỡng chế, nơi nullbị cưỡng chế "null"và một bài kiểm tra "null" == nullđã được thông qua. Nó không thể. Tôi đã gần, nhưng rất, rất sai. Xin lỗi vì điều đó!

Kể từ đó tôi đã thực hiện rất nhiều vấn đề trên wonderfl.net và truy tìm mã mx.rpc.xml.*. Tại dòng 1795 của XMLEncoder(trong nguồn 3,5), trong setValue, tất cả các mã XMLEncoding sôi xuống

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

về cơ bản giống như:

currentChild.appendChild("null");

Mã này, theo fiddle ban đầu của tôi, trả về một phần tử XML trống. Nhưng tại sao?

Nguyên nhân

Theo bình luận viên Justin Mclean về báo cáo lỗi FLEX-33664 , sau đây là thủ phạm (xem hai bài kiểm tra cuối cùng trong fiddle của tôi để xác minh điều này):

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
}

Khi currentChild.appendChildđược truyền chuỗi "null", trước tiên, nó chuyển đổi nó thành một phần tử XML gốc bằng văn bản nullvà sau đó kiểm tra phần tử đó với chữ null. Đây là một thử nghiệm tính bằng nhau yếu, do đó, XML chứa null bị ép buộc thành loại null hoặc loại null bị ép buộc với một phần tử xml gốc có chứa chuỗi "null" và thử nghiệm vượt qua nơi mà nó được cho là sẽ thất bại. Một cách khắc phục có thể là luôn luôn sử dụng các kiểm tra công bằng nghiêm ngặt khi kiểm tra XML (hoặc bất cứ điều gì, thực sự) về "tính không".

Giải pháp

Cách giải quyết hợp lý duy nhất tôi có thể nghĩ đến, đó là sửa lỗi này trong mọi phiên bản ActionScript chết tiệt, là kiểm tra các trường cho "null" và thoát chúng dưới dạng giá trị CDATA .

Giá trị CDATA là cách thích hợp nhất để thay đổi toàn bộ giá trị văn bản có thể gây ra sự cố mã hóa / giải mã. Mã hóa hex, ví dụ, có nghĩa là cho các ký tự riêng lẻ. Giá trị CDATA được ưu tiên khi bạn thoát toàn bộ văn bản của một phần tử. Lý do lớn nhất cho việc này là nó duy trì khả năng đọc của con người.


298

Trên ghi chú xkcd , trang web Bobby Bàn có lời khuyên tốt để tránh việc giải thích dữ liệu người dùng không đúng (trong trường hợp này là chuỗi "Null") trong các truy vấn SQL bằng nhiều ngôn ngữ khác nhau, bao gồm cả ColdFusion .

Không rõ ràng từ câu hỏi rằng đây là nguồn gốc của vấn đề, và đưa ra giải pháp được ghi chú trong một nhận xét cho câu trả lời đầu tiên (nhúng các tham số trong cấu trúc) có vẻ như đó là một vấn đề khác.


239

Vấn đề có thể nằm ở bộ mã hóa SOAP của Flex. Hãy thử mở rộng bộ mã hóa SOAP trong ứng dụng Flex của bạn và gỡ lỗi chương trình để xem cách xử lý giá trị null.

Tôi đoán là, nó được thông qua là NaN (Không phải là số). Điều này đôi khi sẽ làm xáo trộn quá trình xử lý tin nhắn SOAP (đáng chú ý nhất là trong máy chủ JBoss 5 ...). Tôi nhớ việc mở rộng bộ mã hóa SOAP và thực hiện kiểm tra rõ ràng về cách xử lý NaN.


12
name = "Null" dĩ nhiên là hữu ích và tôi không thấy nó nên liên quan đến NaN như thế nào.
eckes

129

@ doc_180 có khái niệm đúng, ngoại trừ anh ta tập trung vào các con số, trong khi người đăng ban đầu có vấn đề với chuỗi.

Giải pháp là thay đổi mx.rpc.xml.XMLEncodertập tin. Đây là dòng 121:

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

(Tôi đã xem xét Flex 4.5.1 SDK; số dòng có thể khác nhau trong các phiên bản khác.)

Về cơ bản, việc xác thực không thành công vì 'nội dung là null' và do đó, đối số của bạn không được thêm vào Gói SOAP đi; do đó gây ra lỗi tham số bị thiếu.

Bạn phải mở rộng lớp này để loại bỏ xác nhận. Sau đó, có một quả cầu tuyết lớn lên chuỗi, sửa đổi SOAPEncoder để sử dụng XMLEncoder đã sửa đổi của bạn và sau đó sửa đổi Hoạt động để sử dụng SOAPEncoder đã sửa đổi của bạn và sau đó sử dụng WebService thay thế để sử dụng lớp Hoạt động thay thế của bạn.

Tôi đã dành một vài giờ cho nó, nhưng tôi cần phải tiếp tục. Nó có thể sẽ mất một hoặc hai ngày.

Bạn có thể chỉ cần sửa dòng XMLEncoder và thực hiện một số bản vá khỉ để sử dụng lớp của riêng bạn.

Tôi cũng sẽ thêm rằng nếu bạn chuyển sang sử dụng RemoteObject / AMF với ColdFusion, null sẽ được thông qua mà không gặp vấn đề gì.


16/11/2013 cập nhật :

Tôi có thêm một bổ sung gần đây vào nhận xét cuối cùng của tôi về RemoteObject / AMF. Nếu bạn đang sử dụng ColdFusion 10; sau đó các thuộc tính có giá trị null trên một đối tượng được xóa khỏi đối tượng phía máy chủ. Vì vậy, bạn phải kiểm tra sự tồn tại của các thuộc tính trước khi truy cập nó hoặc bạn sẽ gặp lỗi thời gian chạy.

Kiểm tra như thế này:

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

Đây là một sự thay đổi trong hành vi từ ColdFusion 9; trong đó các thuộc tính null sẽ biến thành các chuỗi rỗng.


Chỉnh sửa 12/6/2013

Vì có một câu hỏi về cách xử lý null, đây là một ứng dụng mẫu nhanh để chứng minh một chuỗi "null" sẽ liên quan đến từ null dành riêng như thế nào.

<?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>

Đầu ra theo dõi là:

chuỗi null không bằng từ dành riêng null bằng cách sử dụng điều kiện! =

chuỗi null không bằng từ dành riêng null bằng cách sử dụng điều kiện ==

chuỗi null không bằng từ dành riêng null bằng điều kiện ===


8
@ Reboog711 Họ của nhân viên có nghĩa đen là chuỗi "Null" như trong "Tên tôi là Pat Null" Câu trả lời của bạn không vượt qua họ của nhân viên. Bạn trả lời chỉ che giấu sự thật rằng "Null" đang bị ép buộc một cách không phù hợp vào khái niệm ngôn ngữ null bằng phương thức appendChild () như mô tả của Ben Burns. Kết quả là hệ thống vẫn thất bại trong việc đối phó với ông hoặc bà Null.
Maxx Daymon

2
@MaxxDaymon Tôi nghĩ bạn hiểu sai câu trả lời của tôi thực sự là gì. Nó không đưa ra một giải pháp; mà là một lời giải thích tại sao vấn đề xảy ra; và trích dẫn mã có liên quan từ Flex Framework. Chỉnh sửa gần đây của tôi có lẽ là thất lạc; vì nó thảo luận về một cách tiếp cận thay thế và không liên quan trực tiếp đến câu hỏi ban đầu.
JeffryHouser

1
Bạn đang đi đúng hướng, nhưng tại thời điểm đó trong mã contentlà chuỗi "null"và "null" == null trả về sai, do đó kiểm tra hoạt động như dự định. Thay vào đó, tôi tin rằng vấn đề là sự pha trộn về cách XML.appendChild xử lý một đối số chuỗi và làm thế nào một phần tử XML gốc chỉ chứa chuỗi "null" có thể được ép buộc thành một chữ null.
Ben Burns

@ Reboog711 Hãy xem fiddle của tôi. "null"! = null` trở lại truelà hành vi mong muốn ở đây. Nếu điều ngược lại xảy ra, điều này sẽ loại bỏ chuỗi "null" khỏi quá trình mã hóa, thực tế nó sẽ là nguyên nhân của vấn đề. Tuy nhiên, vì thử nghiệm này thành công, bộ mã hóa vẫn tiếp tục, cho đến khi XML.appendChild loại bỏ nó do lỗi ép buộc.
Ben Burns

4
Đừng lo lắng. Nếu bạn muốn xem vấn đề thực sự thêm var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s);vào mẫu mã của bạn.
Ben Burns

65

Dịch tất cả các ký tự thành tương đương thực thể hex của chúng. Trong trường hợp này, Nullsẽ được chuyển đổi thành&#4E;&#75;&#6C;&#6C;


41
Xin đừng làm điều này. CDATA được tạo để sử dụng trong trường hợp bạn cần thoát toàn bộ khối văn bản.
Ben Burns

4
Tôi có thể sai, nhưng tôi không nghĩ rằng hạ thấp chỉ vì đó không phải là giải pháp của bạn là nó hoạt động như thế nào. Ngoài ra, bạn phải ghi nhớ vấn đề yêu cầu một giải pháp heuristic vì không có một cách rõ ràng nào, như đã được chứng minh bằng nhiều giải pháp được đăng. Cuối cùng, hãy nhớ rằng tôi không biết CF, bộ giải mã sẽ không đánh đồng văn bản bên trong của <message> <! [CDATA [NULL]]> </ message> với văn bản bên trong của <message> NULL </ tin nhắn>? Nếu vậy, thì CDATA có thực sự là một giải pháp không?
doogle

7
Tôi downvote vì đây là một mô hình chống. Lỗi trong trường hợp này không phải ở CF, đó là ở ActionScript. Tuy nhiên, dù sao bạn cũng nêu ra một điểm tốt. Tôi sẽ thêm một bài kiểm tra vào fiddle của tôi để mã hóa CDATA.
Ben Burns

51

Việc xâu chuỗi một nullgiá trị trong ActionScript sẽ cho chuỗi "NULL". Sự nghi ngờ của tôi là ai đó đã quyết định rằng, do đó, một ý tưởng tốt để giải mã chuỗi "NULL"null, gây ra sự phá vỡ mà bạn thấy ở đây - có thể là do họ đã truyền vào nullcác đối tượng và nhận chuỗi trong cơ sở dữ liệu, khi họ không muốn điều đó (vì vậy hãy chắc chắn kiểm tra loại lỗi đó).


Vâng, có một số khả năng ở đây sẽ yêu cầu gỡ lỗi nhiều hơn để thu hẹp. 1) WSDL được sử dụng ở đây có đủ biểu cảm để phân biệt giữa "NULL" là giá trị chuỗi và giá trị null thực tế (hoặc bị bỏ qua) không? 2) Nếu vậy, máy khách có mã hóa tên cuối cùng một cách chính xác (dưới dạng chuỗi chứ không phải bằng chữ không) 3) Nếu vậy, dịch vụ có diễn giải đúng "NULL" dưới dạng chuỗi hay ép buộc thành giá trị null không?
pimlottc

39

Là một hack, bạn có thể xem xét xử lý đặc biệt ở phía máy khách, chuyển đổi chuỗi 'Null' thành thứ gì đó sẽ không bao giờ xảy ra, ví dụ, XXNULLXX và chuyển đổi trở lại trên máy chủ.

Nó không đẹp, nhưng nó có thể giải quyết vấn đề cho trường hợp ranh giới như vậy.


32
XXNULLXX cũng có thể là một cái tên. Bạn không biết. Có thể mọi người ở Indonesia không có họ và sử dụng biến thể của XXX làm họ của họ khi được yêu cầu.
gb.

3
Cùng một khái niệm, nhưng cập nhật tất cả các tên trong cơ sở dữ liệu và lời nói đầu sau đó với một số ký tự (1Null, 1Smith). Loại bỏ nhân vật đó trong máy khách. Tất nhiên đây có thể là công việc mite hơn giải pháp của Reboog.
bobpaul

14
@BenBurns Vâng, nhưng nếu tôi muốn đặt tên cho con tôi &#78;&#117;&#108;&#108;thì sao?
Còi báo

@Sirens Đó không phải là vấn đề. Nếu tên của tôi là "<& quot;>", thì tôi hy vọng tên đó sẽ được thoát đúng như & quot; & lt; & amp; quot; & gt; & quot;, không cần phải nói. Vấn đề thực sự là với một ứng dụng hoạt động như thể nó sử dụng danh sách đen cho tên.
Ông Lister

30

Chà, tôi đoán rằng việc triển khai Bộ mã hóa SOAP của Flex dường như tuần tự hóa các giá trị null không chính xác. Nối tiếp chúng dưới dạng String Null dường như không phải là một giải pháp tốt. Phiên bản chính xác có vẻ là để chuyển một giá trị null là:

<childtag2 xsi:nil="true" />

Vì vậy, giá trị của "Null" sẽ không có gì khác ngoài một chuỗi hợp lệ, đó chính xác là những gì bạn đang tìm kiếm.

Tôi đoán việc sửa lỗi này trong Apache Flex không nên khó thực hiện. Tôi khuyên bạn nên mở một vấn đề Jira hoặc liên hệ với những người trong danh sách gửi thư apache-flex. Tuy nhiên điều này sẽ chỉ sửa chữa phía khách hàng. Tôi không thể nói nếu ColdFusion có thể hoạt động với các giá trị null được mã hóa theo cách này.

Xem thêm bài đăng trên blog của Radu Cotescu Cách gửi giá trị null trong các yêu cầu xà phòng .


6
Có thông tin tốt ở đây, vì vậy tôi sẽ không downvote, nhưng tôi cho rằng nó đáng để nhận xét. Theo mặc định, XMLEncoder.as thực sự sẽ mã hóa một nullgiá trị thực đúng, bằng cách đặt xsi:nil="true"vào phần tử. Vấn đề thực sự có vẻ là do cách XMLloại ActionScript (không phải bộ mã hóa) xử lý chuỗi "null".
Ben Burns

22

Đó là một kludge, nhưng giả sử có một chiều dài tối thiểu cho SEARCHSTRING, ví dụ 2 ký tự, substringcác SEARCHSTRINGtham số ở nhân vật thứ hai và vượt qua nó như hai tham số thay vì: SEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). Concatenatehọ trở lại với nhau khi thực hiện truy vấn cơ sở dữ liệu.


32
CDATA đã được thêm vào đặc tả XML để tránh các loại bùn này.
Ben Burns

8
Không cần phải thoát "Null" với CDATA, không có thứ gọi là từ khóa null trong XML.
eckes

6
Đồng ý với @eckes. Tôi không hiểu tại sao có tất cả bài nói về CDATA này. CDATA chỉ hữu ích để thoát các ký tự có ý nghĩa đặc biệt trong XML. không ai trong số: n, u, lcó ngữ nghĩa đặc biệt trong XML. "NULL" và "<! [CDATA [NULL]]>" giống hệt với trình phân tích cú pháp XML.
jasonkarns

9
@jasonkarns - Tôi đồng ý 100% rằng sẽ không có gì đặc biệt về nút chuỗi / nút văn bản NULL, nhưng phải là mô phạm <blah>null</blah><blah><![CDATA[null]]>không giống với trình phân tích cú pháp XML. Họ nên tạo ra cùng một kết quả, tuy nhiên luồng logic để xử lý chúng là khác nhau. Đó là hiệu ứng này mà chúng tôi khai thác như một cách khắc phục lỗi trong triển khai XML flex. Tôi ủng hộ điều này hơn các cách tiếp cận khác vì nó bảo tồn tính dễ đọc của văn bản và không có tác dụng phụ cho các trình phân tích cú pháp khác.
Ben Burns
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.