Как добавить декодер utf8 для решения проблемы искаженных символов в запросе http флаттера? - PullRequest
0 голосов
/ 29 апреля 2020

Я использую эту модель топологии для анализа Json данных. Данные становятся искаженными, когда я получаю китайские символы.

Я пытался добавить utf8.decode наподобие

List<Client> clientFromJson(String str) => List<Client>.from(json.decode(utf8.decode(str)).map((x) => Client.fromJson(x)));

, но среда IDE сообщает мне, что "тип аргумента" String "нельзя назначить типу параметра" List '".

Что мне нужно сделать, чтобы добавить в модель декодер utf8?

///topology.dart

// To parse this JSON data, do
//
//     final client = clientFromJson(jsonString);
//     final topology = topologyFromJson(jsonString);

import 'dart:convert';

List<Client> clientFromJson(String str) => List<Client>.from(json.decode(str).map((x) => Client.fromJson(x)));

String clientToJson(List<Client> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

List<Topology> topologyFromJson(String str) => List<Topology>.from(json.decode(str).map((x) => Topology.fromJson(x)));

String topologyToJson(List<Topology> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Topology {
  String location;
  String mode;
  String macAddress;
  String ipAddress;
  String downloadSpeed;
  String downloadSpeedUnit;
  String uploadSpeed;
  String uploadSpeedUnit;
  List<Client> client;

  Topology({
    this.location,
    this.mode,
    this.macAddress,
    this.ipAddress,
    this.downloadSpeed,
    this.downloadSpeedUnit,
    this.uploadSpeed,
    this.uploadSpeedUnit,
    this.client,
  });

  factory Topology.fromJson(Map<String, dynamic> json) => Topology(
    location: json["location"],
    mode: json["mode"],
    macAddress: json["macAddress"],
    ipAddress: json["ipAddress"],
    downloadSpeed: json["downloadSpeed"],
    downloadSpeedUnit: json["downloadSpeedUnit"],
    uploadSpeed: json["uploadSpeed"],
    uploadSpeedUnit: json["uploadSpeedUnit"],
    client: List<Client>.from(json["client"].map((x) => Client.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "location": location,
    "mode": mode,
    "macAddress": macAddress,
    "ipAddress": ipAddress,
    "downloadSpeed": downloadSpeed,
    "downloadSpeedUnit": downloadSpeedUnit,
    "uploadSpeed": uploadSpeed,
    "uploadSpeedUnit": uploadSpeedUnit,
    "client": List<dynamic>.from(client.map((x) => x.toJson())),
  };
}

class Client {
  String hostname;
  String macAddress;
  String ipAddress;
  String deviceType;
  String connectedNebula;
  String connectionType;
  String connectTime;

  Client({
    this.hostname,
    this.macAddress,
    this.ipAddress,
    this.deviceType,
    this.connectedNebula,
    this.connectionType,
    this.connectTime,
  });

  factory Client.fromJson(Map<String, dynamic> json) => Client(
    hostname: json["hostname"],
    macAddress: json["macAddress"],
    ipAddress: json["ipAddress"],
    deviceType: json["deviceType"],
    connectedNebula: json["connectedNebula"],
    connectionType: json["connectionType"],
    connectTime: json["connectTime"],
  );

  Map<String, dynamic> toJson() => {
    "hostname": hostname,
    "macAddress": macAddress,
    "ipAddress": ipAddress,
    "deviceType": deviceType,
    "connectedNebula": connectedNebula,
    "connectionType": connectionType,
    "connectTime": connectTime,
  };
}

// main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]); 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Topology',
      theme: ThemeData(),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  final String title;

  const Home({Key key, this.title}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var topologies = const [];

  Future loadTopologyList() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String managementPassword = prefs.getString("management_password");
    String username = 'admin';
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$managementPassword'));
    final String url ="some url";
    bool trustSelfSigned = true;
    HttpClient httpClient = HttpClient()
      ..badCertificateCallback =
      ((X509Certificate cert, String host, int port) => trustSelfSigned);
    IOClient ioClient = IOClient(httpClient);

    final response = await ioClient.get(url,
      headers: <String, String>{'authorization': basicAuth},
    );
    ioClient.close();
    String content = response.body;
    setState(() {
      topologies = topologyFromJson(content);
    });
  }

  void initState() {
    loadTopologyList();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFFAFAFA),
      appBar: AppBar(),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.fromLTRB(17, 0, 0, 0),
            child: Text('Topology'),
          ),
          Expanded(
            child: ListView.separated(
              itemCount: topologies.length,
              separatorBuilder: (context, index) => Divider(),
              itemBuilder: (BuildContext context, int index) {
                Topology topology = topologies[index]; 

                return ListTile(
                  title: Text(
                    topology.location,
                  ),
                  leading: CircleAvatar(
                      child: Image.asset(
                          "assets/drawable-mdpi/app_icon_circle.png")),
                  onTap: () {
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Вы должны передать response.bodyBytes при использовании utf8.decode.

Например:

json.decode(utf8.decode(response.bodyBytes))

и если у вас есть строка, то вы можете использовать следующий код для декодирования.

utf8.decode(someString.runes.toList()),
0 голосов
/ 30 апреля 2020

Я получил эту ошибку: Необработанное исключение: тип 'Список' не является подтипом типа 'Строка'

Я получил эту ошибку, когда я изменял файл topology.dart

List<Client> clientFromJson(String str) => List<Client>.from(json.decode(utf8.decode(str.runes.toList())).map((x) => Client.fromJson(x)));

String clientToJson(List<Client> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

List<Topology> topologyFromJson(String str) => List<Topology>.from(json.decode(utf8.decode(str.runes.toList())).map((x) => Topology.fromJson(x)));

String topologyToJson(List<Topology> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

и в main.dart

final json = jsonDecode(utf8.decode(response.bodyBytes));
    setState(() {
      topologies = topologyFromJson(json);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...