Как убедить SOAP :: Lite возвращать данные UTF-8 в ответах как UTF-8? - PullRequest
1 голос
/ 20 февраля 2012

Я пытаюсь передать строки UTF-8 в сложных структурах данных с помощью SOAP :: Lite.Однако, как выясняется, SOAP :: Lite тихо преобразует все строки UTF-8 в октеты с кодировкой base-64 .Проблема в том, что десериализация не возвращает преобразование , а только прямое декодирование base64 .

Это оставляет меня в замешательстве относительно того, как предполагается, что пользовательчтобы убедиться, что они получают данные UTF-8 из ответа SOAP :: Lite.Ходить по дереву и запускать decode_utf8 по всем строкам кажется расточительным.

Любые предложения?

Редактировать: В двух словах, как я могу этот тест пройти без обезьяны-patching

Ответы [ 2 ]

2 голосов
/ 26 июля 2012

Я только что столкнулся с той же проблемой и нашел обсуждение выше полезным. Как вы говорите в OP, проблема в том, что данные кодируются в base64, и флаг is_utf8 теряется. то, что происходит в serlializer, обрабатывает любую строку с не-ascii символом как двоичную. Я сделал это, чтобы сделать то, что я хотел, настроив сериализатор, как показано ниже. Это может иметь странные последствия, но это работает в моей ситуации ..

use strictures;
use Test::More;
use SOAP::Lite;
use utf8;
use Data::Dumper;

my $data = "mü\x{2013}";
my $ser = SOAP::Serializer->new;
$ser->typelookup->{trick_into_ignoring} = [9, \&utf8::is_utf8 ,'as_utf8_string'];
my $xml = $ser->envelope( freeform => $data ); 
my ( $cycled ) = values %{ SOAP::Deserializer->deserialize( $xml )->body };

is( length( $data ), length( $cycled ), "UTF-8 string is the same after serializing" );
done_testing;

sub check_utf8 {
    my ($val) = @_;
    return utf8::is_utf8($val);
}


package SOAP::Serializer;
sub as_utf8_string {
    my $self = shift;
    my($value, $name, $type, $attr) = @_;
    return $self->as_string($value, $name, $type, $attr);
}
1;

9 означает, что проверка utf8 выполняется перед проверкой не-ascii символов. если флаг utf8 включен, он обрабатывает его как «нормальную» строку.

0 голосов
/ 21 февраля 2012

Использование is_utf8 (строка 278) - зло и неправильно. Поскольку мы не можем доверять SOAP :: Lite правильному кодированию символьных данных (честно говоря, этот код, вероятно, был написан до того, как в сообществе появилось слово, как выполнять этот конкретный вид обработки строк), мы дадим ему только данные октетов. и, следовательно, должны сами обрабатывать кодирование / декодирование. Выберите одну кодировку, примените ее перед передачей данных в S :: L, измените ее после получения данных.

use utf8;
use strictures;
use Encode qw(decode encode);
use SOAP::Lite qw();
use Test::More;

my $original = 'mü';
my $xml      = SOAP::Serializer->envelope(
    freeform => encode('UTF-8', $original, Encode::FB_CROAK | Encode::LEAVE_SRC)
);
my ($roundtrip) = map {
    decode('UTF-8', $_, Encode::FB_CROAK | Encode::LEAVE_SRC)
} values %{SOAP::Deserializer->deserialize($xml)->body};

is(length($original), length($roundtrip),
    'Perl character string round-trips without changing length');
done_testing;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...