HTTP Flutter request sending xml data to body

Asked

Viewed 998 times

0

I would like help processing an HTTP request in Flutter (in this case using the SEARCH method to filter files on a Webdav (Nextcloud) file server where I need to send XML type data in the request body.

[x] I can execute the command via Curl using the --data parameter:

curl -u user:senha -X SEARCH 'https://host123.com.br/remote.php/dav' -H "content-Type: text/xml" --data '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>'

[x] I can also process via Postman:

Postman

[ ] I’m not able to process this request that needs to send a body inside Flutter/Dart. For all other HTTP requests of the project we use pkg DIO, which is working well, in which it is not necessary to send a body. The nearest code is this below:

void _list() async {
final prefs = await SharedPreferences.getInstance();

var us = prefs.getString('id') ?? '';
var sn = prefs.getString('password') ?? '';

String basicAuth = 'Basic ' + base64Encode(utf8.encode('$us:$sn'));

try {
  Dio dio = new Dio();
  dio.options.method = 'SEARCH';
  dio.options.responseType = ResponseType.plain;
  dio.options.headers = {
    HttpHeaders.authorizationHeader: basicAuth,
    'content-Type': 'text/xml'
  };
  String data =
      '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>';

  Response response = await dio.request(
      "https://host123.com.br/remote.php/dav",
      data: data);

  print(response);
} catch (e) {
  print(e);
}}

Server responses range from 400, 404, 500 and 501, depending on how it is sent:

I/flutter ( 6767): DioError [DioErrorType.RESPONSE]: Http status error [400]

Any help is welcome. :)

2 answers

1

Opa beauty, recently I worked with the POST and GET part of flutter using http library, maybe I can try and adapt the code for its functionality in question, I have no way to test the code for you because we do not work with the function you want to use but if it serves as a base here you are using Json as post should be added in pubspec.yaml to the library

http:

the code I use to work with post gets more or less so, you will have to adapt its functionality

Future<Map<String, dynamic>> enviaDosagemToWS(Dosagem medidor) async {

    Usuario user = await RetornaUserLogado.retornaUser();   // retorna o usuário conectado
    String token = user.token;                              // utilizamos um sistema de token para comunicar com o web service

    ConfigHelper hosts = ConfigHelper();            // essa função responsável pela configuração do host do servidor base
    ConfigServidor host = ConfigServidor();         // essa função responsável pela configuração do host do servidor base
    host = await hosts.getHostAtivo() ;             // essa função responsável pela configuração do host do servidor base
    String hostAtivo  = host != null ?              // Verifica se tem algum host configurado
    host.porta.length > 0 ? host.host+":"+host.porta // Retorna host:porta quando ambos tiverem configurados
        : host.host                                 // Retorna somente host quando não tiver porta configurada
        : "";                                       // Retorna vazio se não tiver host configurado
    String linkServidor = host != null ?
    host.servidor != "" ? host.servidor : "" : "";

    Map<String, dynamic> jsonDosagem = {            // aqui é o body no nosso caso
      "filial":     medidor.filial,
      "rota":       medidor.rota,
      "data":       "${medidor.data.replaceAll("/", "-")} 00:00:00",
      "dosagem":    double.parse(medidor.dosagem)
    };

    try {
      String urlMontada = "http://$hostAtivo${linkServidor.toString()}";        // url do nosso servidor configrado

      HttpClient httpClient = new HttpClient();
      HttpClientRequest request = await httpClient.postUrl(Uri.parse(urlMontada));
      request.headers.add("Content-type", "application/json");
      request.headers.add("Accept", "application/json");    // nós utilizamos web service em C# talvez tenha que mudar o header de acordo com sua usabilidade   
      request.headers.add("Token", token);                  // se você não utilizar token pode remover essa linha
      request.add(utf8.encode(json.encode(jsonDosagem)));

      HttpClientResponse response = await request.close();
      String reply = await response.transform(utf8.decoder).join();     // aguarda o response do webservice
      httpClient.close();

      if (response.statusCode == 200) {     // se deu tudo certo retorna o código ou alguma mensagem configurada no response
        var j = json.decode(reply);
        return {RETORNOJSON: j};
      }
      else if (response.statusCode == 400) {
        return {"enviaDosagemToWS ERROR": "Requisição falhou."};
      } else if (response.statusCode == 401) {
        return {"enviaDosagemToWS ERROR": "Não autorizado."};
      }

    } catch (e) {
      return {"enviaDosagemToWS ERROR": "Exception: ${e.toString()}"};
    }
    return null;
  }

if you have any questions please do not hesitate to ask

  • Thanks @Matheus I managed to solve.

  • Oops ball show then, abrass

1


I was able to solve it with the answer to that question I had asked at Stackoverflow Global. https://stackoverflow.com/questions/58399365/flutter-http-request-send-using-xml-body

Using the http package:

import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;

main() async {
  var username = 'foo';
  var password = 'B@r!';
  var credential = base64.encode(utf8.encode('$username:$password'));
  var client = http.IOClient();

  var request = http.Request(
    'SEARCH',
    Uri.parse('https://host123.com.br/remote.php/dav'),
  );
  request.headers.addAll({
    HttpHeaders.authorizationHeader: 'Basic $credential',
    'content-type': 'text/xml' // or text/xml;charset=utf-8
  });

  var xml = '<?xml version="1.0" encoding="UTF-8"?>...';
  // either
  request.body = xml;
  // which will encode the string to bytes, and modify the content-type header, adding the encoding
  // or
  // request.bodyBytes = utf8.encode(xml);
  // which gives you complete control over the character encoding

  var streamedResponse = await client.send(request);
  print(streamedResponse.statusCode);

  var responseBody =
      await streamedResponse.stream.transform(utf8.decoder).join();
  print(responseBody);
  client.close();
}

See you around.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.