Dart: Get POST parameters on server side - dart

I send some data from client side using POST request
var value = new Map<String, String>();
value["param1"] = 'value1';
value["param2"] = 'value2';
value["param3"] = 'value3';
HttpRequest.postFormData('http://localhost:8080/', value);
and try to get this data on the server side:
HttpServer.bind(InternetAddress.ANY_IP_V6, 8080).then((server) {
server.listen((HttpRequest request) {
//TODO: process POST request
});
});
But how can I get POST values from the request as Map< string, string>?
upd 1
But as I see result of
var jsonString = await request.transform(UTF8.decoder).join();
depends on type of post message. If I change it result will be
multipart/form-data
------WebKitFormBoundaryoQQD7N0iA5zS8qmg
Content-Disposition: form-data; name="param1"
value 1
------WebKitFormBoundaryoQQD7N0iA5zS8qmg
Content-Disposition: form-data; name="param2"
value 2
------WebKitFormBoundaryoQQD7N0iA5zS8qmg
Content-Disposition: form-data; name="param3"
value 3
------WebKitFormBoundaryoQQD7N0iA5zS8qmg--
text/plain
param1=value 1
param2=value 2
param3=value 3
application/x-www-form-urlencoded
param1=value+1&param2=value+2&param3=value+3
As I have already asked how can I convert it to Map< string, string>?

Here is a complete tutorial https://www.dartlang.org/docs/tutorials/httpserver/#handling-post
String jsonString = await request.transform(UTF8.decoder).join();
or
Map result = await request.transform(UTF8.decoder).join().then(JSON.decode);

I have the same question, and I didn't find any solution until now. I need to pass a map from client to server, and server to use that map to interrogate a mongodb database. Client send that map, but server receive a string. Any conversion to json return also string, not a map.
On the client side I send a map named query:
await HttpRequest.postFormData('http://localhost:8085/$_coll',query).then((HttpRequest response)
On the server side :
if (request.method == 'POST') {
query = await request.transform(utf8.decoder).join();
}
I've tried to encode/decode to json, but with no success.

Related

Send MultiValueMap as MultiPartFormData in Feign Client

I am trying to convert the below kotlin code from RestTemplate to Feign client. The rest template code sends multiValueMap as request with content-type header multipart/form-data and consumes JSON object as response.
RestTemplate Code:
var headers = HttpHeaders()
headers.contentType = MediaType.MULTIPART_FORM_DATA
headers.add("custom-header", "value")
val body: MultiValueMap<String, Any> = LinkedMultiValueMap()
body.add("field1", "value1")
body.add("field2", "value2")
val requestEntity = HttpEntity(body, headers)
return restTemplate.postForEntity("https://enmf7tx8y37x.x.pipedream.net/", requestEntity, Object::class.java)
In this case the request is sent as below:
Headers:
Host: enmf7tx8y37x.x.pipedream.net
X-Amzn-Trace-Id: Root=1-6303ecb2-19a833a044ab3bf83f74f256
Content-Length: 342
Accept: application/xml, text/xml, application/json, application/*+xml, application/*+json
Content-Type: multipart/form-data;boundary=_MtEGFIF4XK_aOU8QsXstQuCliV1-llj
custom-header: value
X-B3-TraceId: a67561ec329f9a16
X-B3-SpanId: a6cc94e403bfe318
X-B3-ParentSpanId: a67561ec329f9a16
X-B3-Sampled: 1
User-Agent: Apache-HttpClient/4.5.13 (Java/17.0.3)
Accept-Encoding: gzip,deflate
Body:
--_MtEGFIF4XK_aOU8QsXstQuCliV1-llj
Content-Disposition: form-data; name="field1"
Content-Type: text/plain;charset=UTF-8
Content-Length: 6
value1
--_MtEGFIF4XK_aOU8QsXstQuCliV1-llj
Content-Disposition: form-data; name="field2"
Content-Type: text/plain;charset=UTF-8
Content-Length: 6
value2
--_MtEGFIF4XK_aOU8QsXstQuCliV1-llj--
I tried to do the same in Feign client:
code:
/*val headers = HttpHeaders()
headers.contentType = MediaType.MULTIPART_FORM_DATA
headers.add("custom-header", "value")*/
val body: MultiValueMap<String, Any> = LinkedMultiValueMap()
body.add("field1", "value1")
body.add("field2", "value2")
val result = testClient.test("value", body)
Feign Client:
#FeignClient(
value = "testClient",
url = "https://enmf7tx8y37x.x.pipedream.net/"
)
interface TestClient {
#PostMapping(
consumes = [MediaType.MULTIPART_FORM_DATA_VALUE],
produces = [MediaType.APPLICATION_JSON_VALUE]
)
fun test(
#RequestHeader(value = "custom-header") customHeader: String,
#RequestPart("request") request: MultiValueMap<String, Any>
): ResponseEntity<Object>
}
The header are fine but no value present in the body.
Header:
Host: enmf7tx8y37x.x.pipedream.net
X-Amzn-Trace-Id: Root=1-6303ef0f-78c869881a5b27d0707eab9e
Content-Length: 17
Accept: application/json
Authorization: Basic aHlwb2xhYjp0ZXN0c211cmY=
Content-Type: multipart/form-data; charset=UTF-8; boundary=182c75dd399
custom-header: value
X-B3-TraceId: 2989eb4f12e3d417
X-B3-SpanId: 23414bcdf365784c
X-B3-ParentSpanId: 2989eb4f12e3d417
X-B3-Sampled: 1
User-Agent: Java/17.0.3
Body:
--182c75dd399--
I had to add consumes value as multipart/form-data instead of json to get the right header values for Accept and Content-Type.
How can I populate the request using Feign client? If the #RequestPart is String then the value is sent in the body but any other data type like multiValueMap, byteArray, etc were not working
In feign client you cannot use MultiValueMap directly. You have to use MultipartFile datatype for bytearray and for the remaining metadata fields you need to mention each one as a separate argument in the method. Then FeignClient will generate the same request like the one you showed when using RestTemplate.
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestPart
import org.springframework.web.multipart.MultipartFile
#FeignClient(
value = "testClient",
url = "https://enmf7tx8y37x.x.pipedream.net/"
)
interface TestClient {
#PostMapping(
consumes = [MediaType.MULTIPART_FORM_DATA_VALUE],
produces = [MediaType.APPLICATION_JSON_VALUE]
)
fun test(
#RequestHeader(value = "custom-header") customHeader: String,
#RequestPart(name = "file") file: MultipartFile,
#RequestPart(name = "field1") field1: String
): ResponseEntity<Object>
}
code sample for How to create MultiPartFile:
import org.springframework.mock.web.MockMultipartFile
//val multipartFile: MultipartFile = MockMultipartFile("filename", byteArray)
val multipartFile: MultipartFile = MockMultipartFile("filename", "filename", "content type like application/pdf", byteArray)

How to post parameters from angular to rails server

I am fairly new to angular and i am trying to send a name and image file to my server which is written in rails. But the data i am being received on my server is not correct and i have tried many fixes but nothing seems to be working. The request payload that being sent is this
-----WebKitFormBoundaryhRvQy5dRArcb6BfP
Content-Disposition: form-data; name="project[logo]"; filename="badge.png"
Content-Type: image/png
------WebKitFormBoundaryhRvQy5dRArcb6BfP
Content-Disposition: form-data; name="project[name]"
abc
------WebKitFormBoundaryhRvQy5dRArcb6BfP--
This is not being accepted in rails server and returns me a bunch of gibberish in the console/log
��2˾F
2ƺx���;p}}�0���'�C�F
��b7�Ӡ�}��c��Ii���W8��I#�<dy���}4�|���{c��5�iV�#�����*�����'��
:ظ׻�<+�I5��^��ԓk�qi���R91R��pi7QZϢ�����V�m��� �(��8�m�c%OGN#�k��k2�>_O�����^Ya��+�����1������^�����K�3�07q���{7�ܶ0+��&sZ�򽽴���w7�>f�^��A�/����d�����g�i�
PG?_��u�����5�i2��F$��\7(�ԟ�t8e9�3�9=Lk�#��ֽ��3��%FJ�QjI����f���qmI4֍4�^��P|�S���)Ԋ0Җ�AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE�����͊O6c��>y?횜����5�Z��Nuf��qr}ݶK�N�K�k̨BU'E^Ri/�W���G/�C�W?f��
RT������ׯ!�8a\�z�_^���Z�ݺEm�(��|��GJ�iS�8�k�{��ۻ��#��+"(��(�`��+��(��(��(��$��"��
2:�V��G��j���K`�S�LI���s�C�����+�����-h)[��q�
��/�^洫T��NMw[�^�z?]���%��ki
z�ͭ��f+��T��a���� S��H:��dz���{2���5
���A#���qڇ��t�D�D2LGz�q��`��nM|�/)�B�z���K��^p__�
���
This is my service.ts
postCreateProject(logo, name)
{
const formData: FormData = new FormData();
const url = EndPoints.BASE_URL + EndPoints.Projects;
formData.append('project[logo]', logo);
formData.append('project[name]', name)
console.log(formData.get('project[logo]'))
return this.httpService.postFileUpload(url, formData);
This is my postFileUpload in the httpService
postFileUpload(url: string, fmd: FormData): Observable<any> {
console.log('post file upload')
const headers = new HttpHeaders();
headers.append('Form-Data','FileUpload');
// headers.set('Content-Type', 'multipart/form-data');
// headers.set('Accept', 'application/json');
return this.http.post(url, fmd, {headers : headers});
}
If you need additional files please ask. Thanks for helping.
If you're using rails 5+ and angular 4+, you might try excluding the headers and just having
return this.http.post(url, fmd).
That's what I do (rails 6 with angular 10) and the data on the rails end is correct.

Can I can return json list from HttpClientResponse

I am trying to connect with our server using dart and flutter. I get an error in certificate server, I get the code and I get response exactly, but the problem is the response keeps coming back as a string. I want it as a list to loop through it.
HttpClient client = new HttpClient();
client.badCertificateCallback =((X509Certificate cert, String host, int port) => true);
String url ='https://xxx';
//Map map = { "email" : "email" , "password" : "password"};
HttpClientRequest request = await client.getUrl(Uri.parse(url));
//request.headers.set('content-type', 'application/json');
//request.add(utf8.encode(json.encode(map)));
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);
I have simple code to get a JSON response as a list. The problem is our server is using https and nginx to take all request to the correct port. Previous code worked but I need to respond with a list.
simple code is :
String apiURL = "https://jsonplaceholder.typicode.com/posts";
http.Response response = await http.get(apiURL);
return json.decode(response.body);
You won't get a list. You would get flat json which you would need to process. Processing can be done using simple script using powershell.

How do I can iterate cookie values from http response?

I am using rest API in my flutter app. For further request I need JSESSIONID which I received from my profile API. I successful got response but I need guide to iterate cookie value.
I followed following steps:
final response = await http.get(
strURL,
headers: {
"Authorization": basicAuth,
"Content-Type": "application/json"
},
);
String rawCookie = response.headers['set-cookie'];
print('rawCookie $rawCookie');
As print raw cookie it is printing details:
flutter: rawCookie __cfduid=d5bbe3f8a131478a78ae996e636cca0401544177738; expires=Sat, 07-Dec-19 10:15:38 GMT; path=/; domain=.rayz.ch; HttpOnly,JSESSIONID=6AD6698C5BFC90F1D089696A955E6824; Path=/; HttpOnly
I can iterate it by substring but I want to iterate it with a proper way. So please guide me on this.
With package:http you need to split the cookie string yourself using String.split. If you want to use the underlying http client, that gives you a pre-parsed list of cookies, for example:
HttpClient _httpClient = new HttpClient();
HttpClientRequest request = await _httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
print(response.cookies); // this is a List<Cookie>
Here is my code which runs perfectly and if any key does not have value, then it shows range error. But as your doubt, this code is running fine.
var headersList = response.headers['set-cookie']!.split(";");
for(var kvPair in headersList){
var kv = kvPair.split("=");
var key = kv[0];
var value = kv[1];
if(key.contains("session_id")){
print(value);
}
}

Response zip file with WebFlux

I am new in Spring 5 and Reactive Programming. My problem is creating the export feature for the database by a rest API.
User hits GET request -> Server reads data and returns data as a zip file. Because zip file is large, so I need to stream these data.
My code as below:
#GetMapping(
value = "/export",
produces = ["application/octet-stream"],
headers = [
"Content-Disposition: attachment; filename=\"result.zip\"",
"Content-Type: application/zip"])
fun streamData(): Flux<Resource> = service.export()
I use curl as below:
curl http://localhost/export -H "Accept: application/octet-stream"
But it always returns 406 Not Acceptable.
Anyone helps?
Thank you so much
The headers attribute of the #GetMapping annotation are not headers that should be written to the HTTP response, but mapping headers. This means that your #GetMapping annotation requires the HTTP request to contain the headers you've listed. This is why the request is actually not mapped to your controller handler.
Now your handler return type does not look right - Flux<Resource> means that you intend to return 0..* Resource instances and that they should be serialized. In this case, a return type like ResponseEntity<Resource> is probably a better choice since you'll be able to set response headers on the ResponseEntity and set its body with a Resource.
Is it right, man? I still feel it's not good with this solution at the last line when using blockLast.
#GetMapping("/vehicle/gpsevent", produces = ["application/octet-stream"])
fun streamToZip(): ResponseEntity<FileSystemResource> {
val zipFile = FileSystemResource("result.zip")
val out = ZipOutputStream(FileOutputStream(zipFile.file))
return ResponseEntity
.ok().cacheControl(CacheControl.noCache())
.header("Content-Type", "application/octet-stream")
.header("Content-Disposition", "attachment; filename=result.zip")
.body(ieService.export()
.doOnNext { print(it.key.vehicleId) }
.doOnNext { it -> out.putNextEntry(ZipEntry(it.key.vehicleId.toString() + ".json")) }
.doOnNext { out.write(it.toJsonString().toByteArray(charset("UTF-8"))) }
.doOnNext { out.flush() }
.doOnNext { out.closeEntry() }
.map { zipFile }
.doOnComplete { out.close() }
.log()
.blockLast()
)
}

Resources