Passing a String List in a SOAP request in Flutter - web-services

I am making a SOAP Request and this is how my request should be sent:
<id></id>
<fieldList>
<string>string</string>
<string>string</string>
</fieldList>
This is how I have built my envelope:
final int id = 21;
List<String> fieldList = new List<String>();
fieldList = [
"pinNumber:PIN0000074",
"dispatchArrivedTime:13.05",
"towedStatus:C"
];
var envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap:Envelope "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
"<soap:Body>"
"<update xmlns=\"http://example.com/\">"
"<id>${id}</id>"
"<fieldList>${fieldList}</fieldList>"
"</update>"
"</soap:Body>"
"</soap:Envelope>";
final response = await http.post(
'http://example.com/vc/ws/towedvehicletable.asmx',
headers: {
"Content-Type": "text/xml; charset=utf-8",
"SOAPAction": "http://example.com/update",
"Host": "example.com"
//"Accept": "text/xml"
},
body: envelope);
However, this approach does not work. It would be really helpful if somebody could show me how to pass a String List into my request. I am using Flutter and Dart. Thanks

Just map list of strings and then join it:
List<String> fieldList = ['test1', 'test2'];
final xmlValues = fieldList.map((v) => '<string>$v</string>').join();
print(xmlValues);
prints:
<string>test1</string><string>test2</string>
There's also a package for working with XML. It allows you to both parse and construct XML documents.

Related

errore with messageSignature sha256 in postman (base64 is notdefined.)

I'm testing an api that i have to send in body those data acording to documentation:
studentId,
apiKey,
timeStamp (current iso time as a string),
messageSignature: apikey+studentId+timeStamp encrypted using sha256,
i wrote a script to generate message signature using sha256 in Pre-request Script.
Pre-request Script:
var dateIso = new Date().toISOString();
pm.globals.set("isoDateTostring", dateIso);
console.log('timestamp var is:', pm.globals.get("isoDateTostring"));
let msg = "apiKeyvalue" + "studentId" + pm.globals.get("isoDateTostring");+ JSON.stringify(msg)
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "secretKey");
hmac.update(msg);
const messageSignature = hmac.finalize().toString();
Details (like screenshots):
in body i wrote:
{
"studentId":"********",
"apiKey":"************",
"timeStamp":{{$isoDateTostring}},
"messageSignature": {{$messageSignature}}
}
when i send the request i get base64 is notdefined.
Code would be like:
In Tab Body:
{{$isoDateTostring}} --> "{{isoDateTostring}}"
{{$messageSignature}} --> "{{messageSignature}}"
{
"studentId": "123",
"apiKey": "123abc",
"timeStamp": "{{isoDateTostring}}",
"messageSignature": "{{messageSignature}}"
}
In tab Pre-request: I fake studentId and apiKey
const dateIso = new Date().toISOString();
pm.globals.set("isoDateTostring", dateIso);
const studentId = "123";
const apiKeyvalue = "123abc"
let msg = apiKeyvalue + studentId + pm.globals.get("isoDateTostring");
const messageSignature = CryptoJS.SHA256(msg).toString();
pm.globals.set("messageSignature", messageSignature);
Result:
{
"studentId": "123",
"apiKey": "123abc",
"timeStamp": "2021-10-26T13:20:09.068Z",
"messageSignature": "783e65ff1cfb2374fb5f84daa35c01d18b8a1898b3a1837e84934e91a3c0720d"
}

Not able to fetch the response json from pm.sendRequest() in postman

I am sending this request in postman
https://postman-echo.com/get?record=aaaa
The tests contain the below code:
let arr = ['aaaa'];
pm.globals.set("arr",arr);
let url = "";
for(i=0;i<arr.length;i++)
{
url="https://postman-echo.com/get?record="+arr[i];
pm.sendRequest(url,(err, response)=>{
console.log("sadsadassdWDEW"+response.json());
});
}
Output in console:
sadsadassdWDEW[object Object]
What I am expecting:
response json
{"args":{"record":"aaaa"},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-604a4c29-4708d1643484d5cf445fb170","user-agent":"PostmanRuntime/7.26.10","accept":"/","cache-control":"no-cache","postman-token":"95ef5af8-5188-4869-ab97-1fcc77f3ff8e","accept-encoding":"gzip, deflate, br","cookie":"sails.sid=s%3ABdpZH_SPae8c7hYqFC_mC-17gASiTxNA.WZtCgV36HDHPyFpP7uKyD9AOOBZnh6UbaCpXTCYUP4U"},"url":"https://postman-echo.com/get?record=aaaa"}
Can you tell me where am I going wrong?
let arr = ['aaaa'];
pm.globals.set("arr",arr);
let url = "";
for(i=0;i<arr.length;i++)
{
url="https://postman-echo.com/get?record="+arr[i];
pm.sendRequest(url,(err, response)=>{
console.log("sadsadassdWDEW"+response.text
());
});
}
use response.text() instead or use JSON.stringify(response.json()) . Insdie console.log we should give string representation of an object, not the object itself

How can I send a PDF document to Google Cloud Document AI using the v1beta3 API?

I have been successful in sending a PDF File stored in GCS to the Document AI v1beta2 API. But in v1beta3 API, the file approach is no longer supported. It requires me to send the content in the JSON. Here is the documentation I am following: https://cloud.google.com/document-ai/docs/form-parser#v1beta3
Some questions:
What if anything do I have to do to the PDF content returned from a GET request? The PDF content appears to be in a base64 string which is what the API requires.
Looking at the API request, do you see anything incorrect?
REQUEST INFORMATION
ID: N/A
Method: POST
URL/Path: https://us-documentai.googleapis.com/v1beta3/projects/38072577434/locations/us/processors/cd8a06d0cd3cb045:process
Headers: Content-Type: application/json, Accept: application/json
Authorization: :censored:6:c2dc31949c: :censored:179:27504afa53:
Params: N/A
Data:
{"document":{"mimeType":"application/pdf","content":["%PDF-1.4\n1 0 obj\n<<\n/Title (��\u0000C\u0000r\u0000y\u0000s\u0000t\u0000a\u0000l\u0000 \u0000R\u0000e\u0000p\u0000o\u0000r\u0000t\u0000 \u0000V\u0000i\u0000e\u0000w\u0000e\u0000r)\n/Creator (��\u0000w\u0000k\u0000h\u0000t\u0000m\u0000l\u0000t\u0000o\u0000p\u0000d\u0000f\u0000 \u00000\u0000.\u00001\u00002\u0000.\u00005)\n/Producer (��\u0000Q\u0000t\u0000 \u00004\u0000.\u00008\u0000.\u00007)\n/CreationDate (D:20201219164504Z)\n>>\nendobj\n3 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n4 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /Annot\n/Subtype /Link\n/Rect [3.75000000 339.500000 102.750000 345.500000 ]\n/Border [0 0 0]\n/A <<\n/Type /Action\n/S /URI\n/URI (http://www.schooldude.com/)\n>>\n>>\nendobj\n9 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n5 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/Contents 10 0 R\n/Resources 12 0 R\n/Annots 13 0 R\n/MediaBox [0 0 595 842]\n>>\nendobj\n12 0 obj\n<<\n/ColorSpace <<\n/PCSp 4 0 R\n/CSp /DeviceRGB\n/CSpg /DeviceGray\n>>\n/ExtGState <<\n/GSa 3 0 R\n>>\n/Pattern <<\n>>\n/Font <<\n/F6 6 0 R\n/F7 7 0 R\n>>\n/XObject <<\n>>\n>>\nendobj\n13 0 obj\n[ 8 0 R ]\nendobj\n10 0 obj\n<<\n/Length 11 0 R\n/Filter /FlateDecode\n>>\nstream\nx��]M�ܸ\u0011����9���o\u0012\b\u0002x>6#\u000e\u0001\f\u001b�!�!�f\u0013,֋8{��\u000fI}t���\u001eq\u001e=�x�X���*=U�*V\u0015)��\u001f?����oͻ���n>�?\u001f>\u001eڣ3m�_���]~�l>9|m�\u001e>\u001c>Ŀ������\u000b꘾)l����_���h�\u0012.~�NM_���/�k~�\u0002\u0007H\"����w\u001d�x�=�����Jex��#��#�x�nU�\u001c~J\b�j�||�s��\u001b��)��s�׿�\u000f<\u0003�}�\u001c���û\u001f�M���O\u0011sV\\��S�z'T�����I\u0015h>�|x��AQ\u0015'�9J\u0019Z�\u001a���\u0007����C8*i������σ<�������r���rF��T�\u0003�8r��|9����7����,od�e���Y�}�gce��a�}�#'�\u0002#B�(M�g��J|�-���d\u001f��3v1�x��]4����E��d�\tc�\u0013�W���\\�\u001a�7w։:���\u000e��Vh�Ą1ZJx���dި���/�~��d�B�8x�\u00030�����|\u001f9TrI�\r�E}tM�\u0015�\u00006J�䉐\u0004�g\u0002o�BB6w��\n .�\u001e��5\u0018��[\u001a�\u0014;�\u0002%�s�D��\f y�c�ډ�Xe���P&+V�L�$f�sEF��\u0018;�ۉ��nkFO�*�,{\u0014V�Q3I܃��)b%S��]���>��ZDɍ�;!#\u000e��\u0018�M�e#\u0016�e���\u001b�w€\u001c��1#Iz��\"�\f\u0018Q�\u0018��n\u0006\u0001�j�\u0002:\u0016�d\u0006d�\\\u0006�(y\f���\u0001���\f�|�[#��[Aw�b��\\�)�xϚ*�f����P�(�\u0012}#\u0015��#\u0015���0r�ȕ\u0018\u0011Z�G��-Y����\\��[�c��\u0018��q1b$�E��h�`�\\\f�������,1�9\u0004�\u0016ۖ�ň��E�D�(���T�p��0r�ȕ\u0018\u0011\u001a6\u0017�es1a$k�*1�$ag:*�3����E�D�hz�������\\�]]#m�'%�'\u0015��ep�I�\\������?�\u0002H�+����O\"��\u001fQ2\u0019���{�#�\u0002W��PǓ�m�\u001c\u0018Q\u00129���v<\u0017T�\u0003]Ӗʁ$�́\u0011%�\u0003�\u0011�\u0013\u000e�Np5\u000etS7T\u000e$�d\u000e�(�\u001c��A;�#�\u000f�Ɓ��M�z)v����V�>�[]BAH_ک�k;5}q'[��vagw���e���ݸ\u001e\by\u0012y�1=�v��z�\u001d�\u0001Y$�\u0001#J\u001e\u0003Rj�\u0013\u0006�̮\u001a\u0003�4�ʀ,�ˀ\u0011%�\u0001)��\t\u0003r^W�\u0001]S�ʀ,�ˀ\u0011%�\u0001�ͳ\u0013\u0006�.O5\u0006�#\u0000����/v�����w9*�P���?#lbbγ|΢O\u0012o������m�Er�?���?��� #���b#�kh��]�\u0001d���.^\u0004H��>\u0018Ѝ��\u0018��5����+�4}\u0005\u0016W�[/���x��!\u0013�k�\u0012F�\u0016�\u0012#Bk�Z�׺\u0012�h-[�\\��1����y�\u0011�Č�\t�$љ,�=�x��bj�\u0019[�w���O\"��\u001fQ��/T�\u000b\u0001Dj�Uc#Ԭf�EF�Ӣ��\u001cD�\u0012�l�~�D��hD��#��^��H]я��3��\u0019`�\fp�a��ɀ�%%�\u0001I$�\u0001#J\u001e\u0003T?<�\u0001J��\fp��\u001f&\"���\n�X�a$o�E�\u0018)�-�$��b�0r�ȕ\u0018\u0011�\u001f~M\u0012�\u000f�v\u0018�Z�J4�\u0011/M�\u0016\"�t�:\u00171�l\u001ckcN��,�=\u0013 [...]
Here is the error I am receiving:
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"content\" at 'document': Proto field is not repeating, cannot start list.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "document",
"description": "Invalid JSON payload received. Unknown name \"content\" at 'document': Proto field is not repeating, cannot start list."
}
]
}
]
}
}
2021-01-05 adding code to show how encoding is perfomed:
//
//Function to call each url in an array of urls
//
const requestAsync = function(url) {
return z.request(url).then((response) => response.content)
}
//
//Create the array of urls to call synchronously
//
var urlArr = [];
const urls = {
url: 'https://storage.googleapis.com/cloud-samples-data/documentai/loan_form.pdf',
method: 'GET',
headers: {
'Accept': 'application/pdf',
'raw': true
}
}
urlArr.push(urls);
//
//Call the function for each item in the urlArr
//
return Promise.all(urlArr.map(requestAsync))
.then(function(values){
//
// Convert the file data to a Buffer and base64 encode it.
//
var fileContent = Buffer.from(values[0]).toString('base64');
const options = {
url: 'https://us-documentai.googleapis.com/v1beta3/projects/38072577434/locations/us/processors/cd8a06d0cd3cb045:process',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`
},
body: {
document: {
mimeType: 'application/pdf',
content: fileContent
}
}
};
return z.request(options)
.then((response) => {
response.throwForStatus();
const result = response.json;
// Get all of the document text as one big string
const {text} = result;
// Extract shards from the text field
const getText = textAnchor => {
// First shard in document doesn't have startIndex property
const startIndex = textAnchor.textSegments[0].startIndex || 0;
const endIndex = textAnchor.textSegments[0].endIndex;
return text.substring(startIndex, endIndex);
};
/* // Process the output
const [page1] = result.pages;
const {formFields} = page1;
var fieldList = "";
for (const field of formFields) {
var fieldName = getText(field.fieldName.textAnchor);
var fieldValue = getText(field.fieldValue.textAnchor);
fieldName = fieldName.replace(/\n/g,'');
fieldValue = fieldValue.replace(/\n/g,'');
fieldList += `"${fieldName}": "${fieldValue}"`;
z.console.log(`\t(${fieldName}, ${fieldValue})`);
}
*/
//z.console.log(fieldList)
return {getText};
});
});
It looks like the "content" you used on your request is not in base64. If you are using Linux, you can use the command base64.
base64 your_pdf_to_use.pdf > base64_of_your_pdf.txt
Or you can just use any base64 converter. I saw this online pdf to base64 converter and it works for me as well.
When checking base64 output it should not have any recognizable text/words. I tried using the sample file in the documentAI quickstart. Here is a snippet of a base64 output.
JVBERi0xLjUKJb/3ov4KMiAwIG9iago8PCAvTGluZWFyaXplZCAxIC9MIDI5MDUxIC9IIFsgNzky
IDEzNCBdIC9PIDYgL0UgMjg3NzYgL04gMSAvVCAyODc3NSA+PgplbmRvYmoKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKMyAwIG9iago8PCAv
VHlwZSAvWFJlZiAvTGVuZ3RoIDcwIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9EZWNvZGVQYXJtcyA8
PCAvQ29sdW1ucyA0IC9QcmVkaWN0b3IgMTIgPj4gL1cgWyAxIDIgMSBdIC9JbmRleCBbIDIgMzAg
XSAvSW5mbyAxNyAwIFIgL1Jvb3QgNCAwIFIgL1NpemUgMzIgL1ByZXYgMjg3NzYgICAgICAgICAg
ICAgICAgIC9JRCBbPGFiYjQ5MjJhYTY5N2NmZDJiODVjYjY5YjNhZGI4MDZmPjxhYmI0OTIyYWE2
OTdjZmQyYjg1Y2I2OWIzYWRiODA2Zj5dID4+CnN0cmVhbQp4nGNiZOBnYGJgOAkkmPiABKMRiNsG
YjEACcHDQELhCEhWBkiICYIkpgEJ9ocgliGQEAErrmBgYpwqAdLLwEgxAQD5KwddCmVuZHN0cmVh
bQplbmRvYmoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg....
A snippet of my request.json:
{
"document": {
"mimeType": "application/pdf",
"content": "JVBERi0xLjUKJb/3ov4KMiAwIG9iago8PCAvTGluZWFyaXplZCAxIC9MIDI5MDUxIC9IIFsgNzky
IDEzNCBdIC9PIDYgL0UgMjg3NzYgL04gMSAvVCAyODc3NSA+PgplbmRvYmoKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKMyAwIG9iago8PCAv
VHlwZSAvWFJlZiAvTGVuZ3RoIDcwIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9EZWNvZGVQYXJtcyA8
PCAvQ29sdW1ucyA0IC9QcmVkaWN0b3IgMTIgPj4gL1cgWyAxIDIgMSBdIC9JbmRleCBbIDIgMzAg
XSAvSW5mbyAxNyAwIFIgL1Jvb3QgNCAwIFIgL1NpemUgMzIgL1ByZXYgMjg3NzYgICAgICAgICAg
ICAgICAgIC9JRCBbPGFiYjQ5MjJhYTY5N2NmZDJiODVjYjY5YjNhZGI4MDZmPjxhYmI0OTIyYWE2
OTdjZmQyYjg1Y2I2OWIzYWRiODA2Zj5dID4+CnN0cmVhbQp4nGNiZOBnYGJgOAkkmPiABKMRiNsG...
}
}
Curl request:
curl -X POST -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) -H "Content-Type: application/json; charset=utf-8" -d #request.json https://us-documentai.googleapis.com/v1beta3/projects/xxxxxxx/locations/us/processors/xxxxxx:process > result.json
Here is the snippet of the output when I used the file from the quick start using endpoint form parser:
EDIT: 20210106
I did try accessing the file using GET and I got the base64 value cleanly using your current request in urls. But I found a SO post about converting files to base64 and says to
add encoding: null on request options so that you will surely
receive a Buffer and not a String
Adding encoding: null worked for me as well. It is worth a shot.
Here is a snippet of my code for GET and encode to base64:
const request_img = require('request');
const urls = {
url: 'https://storage.googleapis.com/cloud-samples-data/documentai/loan_form.pdf',
method: 'GET',
encoding: null,
headers: {
'Accept': 'application/pdf',
'raw': true
}
}
var urlArr = [];
urlArr.push(urls);
request_img(urlArr[0], function(err, res, body) {
var converted_to_base64 = Buffer.from(body).toString('base64');
console.log(converted_to_base64);
});
Here is the snippet of the output. I got the file encoded to base64:
JVBERi0xLjUKJb/3ov4KMiAwIG9iago8PCAvTGluZWFyaXplZCAxIC9MIDI5MDUxIC9IIFsgNzkyIDEzNCBdIC9PIDYgL0UgMjg3NzYgL04gMSAvVCAyODc3NSA+PgplbmRvYmoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKMyAwIG9iago8PCAvVHlwZSAvWFJlZiAvTGVuZ3RoIDcwIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9EZWNvZGVQYXJtcyA8PCAvQ29sdW1ucyA0IC9QcmVkaWN0b3IgMTIgPj4gL1cgWyAxIDIgMSBdIC9JbmRleCBbIDIgMzAgXSAvSW5mbyAxNyAwIFIgL1Jvb3QgNCAwIFIgL1NpemUgMzIgL1ByZXYgMjg3NzY
By the way the version of my NodeJS is v10.14.2
The Document AI Documentation has been updated to include base64 encoding conversion for the Node.js samples
https://cloud.google.com/document-ai/docs/process-documents-client-libraries#client-libraries-usage-nodejs
You can also check out this Codelab for the Form Parser using Node.js. Most of the actual processing request will be the same for every processor.
https://codelabs.developers.google.com/codelabs/docai-form-parser-node#7

Post method not working : jquery spring restful webservice with java

When the service is being called by using method as GET, it works smoothly i.e. request.getParameter("userValue") is printed.
But while using Post method, it prints null for request.getParameter("userValue").
HTML code : (jsonObject has valid json)
var myData = "userValue=" + jsonObject ;
jQuery.ajax({
         type: "POST",
         url: "http://localhost:8080/Webservice_JS_26Oct/FieldsToFile/write",
         data: myData,
         contentType: "application/json; charset=utf-8",
         dataType: "json",
Java Code:
#RequestMapping(value = "/FieldsToFile")
public class FileWriter {
#RequestMapping(value = "/write", method = RequestMethod.POST, produces = "application/json")
public String getData(HttpServletRequest request) throws IOException, IllegalStateException, ServletException {
String jsonString = request.getParameter("userValue") ;
System.out.println("jsonString = " + jsonString);
String myData = request.getParameter("myData") ;
I am new to this, Please advise how to make it work for POST method.
You can use request.getInputStream() to print the request body part. I suggest that your contentType: "application/json; charset=utf-8", can be application/x-www-form-urlencoded or HttpServletRequest request can be #Requestbody ..

Spring MVC File Upload with multipart data and unit test

I am using Spring 4 latest, and I generally have no problem writing RESTful controllers. There is a legacy web-app, which is using java.net.HTTPUrlConnection to do a multi-part upload. There are 3 pieces of data we are uploading:
1 is a PDF file, and we have the bytes, then the other two pieces of data are just 2 string fields.
First let me show you the Spring REST controller to accept the data:
#RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public #ResponseBody boolean saveData(#RequestPart(value = "field1") String field1, #RequestPart(value = "field2") String field2, #RequestParam(value = "pdfbytes") String pdfbytes)
{
System.out.println("saveData: field1=" + field1);
System.out.println("saveData: field2=" + field2);
System.out.println("saveData: pdfbytes=" + pdfbytes);
boolean response = true;
return response;
}
The code in front-end, for sending the data using 'java.net.HttpURLConnection'
looks like this:
String boundary = MultiPartFormOutputStream.createBoundary();
URL uploadDocumentUrl = new URL(protocol + "://" + host + UPLOAD_EDITED_DOCUMENT);
HttpURLConnection urlConn = (HttpURLConnection) MultiPartFormOutputStream.createConnection(uploadDocumentUrl);
urlConn.setRequestProperty("Content-Type", MultiPartFormOutputStream.getContentType(boundary));
urlConn.setRequestProperty("Connection", "Keep-Alive");
urlConn.setRequestProperty("Cache-Control", "no-cache");
urlConn.setRequestProperty("User-Agent", userAgent);
urlConn.setRequestMethod("POST");
MultiPartFormOutputStream out = new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary);
String pdfbytes= getEncodedDocument(pdf);
out.writeField("field1", field1);
out.writeField("field2", field2);
out.writeField("pdfbytes", pdfbytes);
out.close();
int responseCode = urlConn.getResponseCode();
String responseMessage = urlConn.getResponseMessage();
"MultiPartFormOutputStream" is a custom object that was created to send data via HttpUrlConnection, it's pretty standard code. I do trust it at this time.
So, based on how we are sending the data, do I need to change the Controller to do anything different, or does that look ok?
Now here is the code, that I am using to Unit Test that controller:
#Test
public void testMockUpload() throws Exception
{
// Load resource being uploaded
byte[] pdfbytes = getByteArrayFromFile(FILENAME);
MockMultipartFile firstFile = new MockMultipartFile("field1", "", "text/plain", "field1 data".getBytes());
MockMultipartFile secondFile = new MockMultipartFile("field2", "", "text/plain", "field2 data".getBytes());
MockMultipartFile jsonFile = new MockMultipartFile("pdfbytes", "", "text/plain", pdfbytes);
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.fileUpload(BASE_URL + "/save").file(firstFile).file(secondFile).file(jsonFile)
.with(user(USERNAME).roles("role1", "role2")).contentType(MediaType.MULTIPART_FORM_DATA_VALUE);
this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk());
}
And the error I get back now, is:
org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
which I am looking into. If I need to make any changes on how I need to create my test, I am very open to that. Eventually, I will get everything to sync up between the sending code, the receiving controller, and the unit test.
Thanks in advance! As usual, if there is any other data, or information, I can provide, please let me know. Thanks!
To upload one file you would define the RequestParam type as org.springframework.web.multipart.MultipartFile;
#RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public #ResponseBody boolean saveData(#RequestParam(value = "file") MultipartFile file)
{
return response;
}
For Multiple files I'd try creating a Wrapper form:
public class UploadForm{
private List<MultipartFile> files;
}
Bind to this in the controller:
#RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public #ResponseBody boolean saveData(#ModelAttribute uploadForm)
{
return response;
}
and then use Spring's support for indexed fields to bind to a collection:
Test:
MockMultipartFile firstFile = new MockMultipartFile("files[0]", "", "text/plain", "field1 data".getBytes());
MockMultipartFile secondFile = new MockMultipartFile("files[1]", "", "text/plain", "field2 data".getBytes());
MockMultipartFile jsonFile = new MockMultipartFile("files[2]", "", "text/plain", pdfbytes);
Client:
out.writeField("files[0]", file1Bytes);
out.writeField("files[1]", file2Bytes);
...