Flutter image upload to SpringBoot server not working - spring-boot

I'm trying to upload an image from my Flutter application using the following code:
Future<String> saveImage(File image) async {
var stream = new http.ByteStream(DelegatingStream.typed(image.openRead()));
var length = await image.length();
String token = "blah"; //token for authentication
var uri = Uri.parse(url); //I get the URL from some config
Map<String, String> headers = { "Authorization": "Bearer $token", "content-type": "multipart/form-data" };
var request = new http.MultipartRequest("POST", uri);
request.headers.addAll(headers);
var multipartFile = new http.MultipartFile('file', stream, length);
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
But this request fails on my spring-boot server with the following error:
{"timestamp":1562637369179,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present","path":"/api/v1/user/photo"}
This is what my Java controller method looks like:
#RequestMapping(value = "/photo", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> uploadImage(#RequestPart(required = true) #RequestParam("file") MultipartFile image) throws IOException {
}
I would like to mention that the method works if I use postman to upload an image. There seems to be something wrong with my flutter code.
Thanks for any help.

Figured it out. Instead of using the new http.MultipartFile() constructor I used this static method:
request.files.add(await http.MultipartFile.fromPath('file', image.path,
contentType: new MediaType('image', imageType)));

Related

How to download a file from an AJAX response

Im making an AJAX POST request to a spring controller and getting returned an byte array as the response. I want to make it downloadable. What is the best approach to take?
Heres my implementation :
var params = [[${params}]];
$("#download-button").click(function(e) {
e.preventDefault();
$.ajax({
type: "POST",
contentType: "application/json",
url: "/patient-listing/excel",
data: JSON.stringify(params),
success: function(result) {
var byteArray = result;
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([byteArray], { type:'application/octet-stream' }));
a.download = "file.XLSX";
document.body.appendChild(a)
a.click();
document.body.removeChild(a)
},
error: function(result) {
console.log('error');
}
});
});
In here even though the file is downloaded there is no data.
Controller :
#PostMapping(value = "/patient-listing/excel", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity getEmployeeReportXlsx(#RequestBody Param param) {
logger.info("Generating Excel report of param : " + param);
final byte[] data = poiService.getExcelFile(param);
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
header.set(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=case-data-report.xlsx");
header.setContentLength(data.length);
return new ResponseEntity<>(data, header, HttpStatus.OK);
}
You can simply download excel without AJAX request,
Change POST method to GET method using #GetMapping
#GetMapping(value = "/patient-listing/excel", consumes = MediaType.APPLICATION_JSON_VALUE)
in thymeleaf ,
<a class="sidebar-element" th:href="#{/patient-listing/excel}">
Generate Excel
</a>

400 bad request,Is there any problem with the code in controller?

I'm trying to send data to controller by ajax,but met with problem Failed to load resource: the server responded with a status of 400 (Bad Request).I don't know which part of the problem
JS:
var info ={
"questions":{"q1":trim(q1), "q2":trim(q2),"q3":trim(q3),"q4":trim(q4),"q5":trim(q5),"q6":trim(q6),"q7":trim(q7),"q8":trim(q8)},
"answers":{"datetimepicker":datetimepicker,"sexual":sexual,"nation":nation, "province":province,"city":city, "sheng":sheng,"shi":shi,"xian":xian, "height":height,"weight":weight}
};
var info_str = JSON.stringify(info);
$.ajax({
type:'GET',
data:info_str,
contentType: "application/json; charset=utf-8",
dataType: "json",
url :'/yiban',
success :function(data) {
alert(data);
},
error :function(e) {
alert("error");
}
});
Java:
#RequestMapping(value = "/yiban", method = RequestMethod.GET)
public void yiban(HttpServletRequest request)
{
String jsonStr = request.getParameter("info_str");
JSONObject questions = JSONObject.fromObject(jsonStr).getJSONObject("questions");
JSONObject answers = JSONObject.fromObject(jsonStr).getJSONObject("answers");
String q1 = questions.getString("q1");
String ans = answers.getString("nation");
System.out.println(q1);
}
#RequestMapping(value = "/yiban", method = RequestMethod.POST)
public void yiban(HttpServletRequest request) throws IOException {
//GET method parameter is passed with url , json data can't go with url. json or xml is passed in request boy
// String jsonStr = request.getParameter("info_str");
ServletInputStream inputStream = request.getInputStream();
String jsonStr=StreamUtils.copyToString(inputStream, Charset.forName("UTF-8"));
JSONObject questions = JSONObject.fromObject(jsonStr).getJSONObject("questions");
JSONObject answers = JSONObject.fromObject(jsonStr).getJSONObject("answers");
String q1 = questions.getString("q1");
String ans = answers.getString("nation");
System.out.println(q1);
}
Above is my code which works in my project .
Firstly ,use POST to send json or xml!
and use request.getInputStream to receive json data!
Secondly you RequestMappingMethod returns nothing, your front web receive nothing !
What view you want to return to Front?

Why is this RestSharp file upload not working?

I have this ASP.NET Core Web API action method:
[HttpPost("PostDir")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PostDir(string serverPath)
{
// Do stuff with file.
return Ok();
}
I don't know what to do with the file I am trying to upload or what it looks like in the action method because the action is never invoked: the client code below gets a 404 response:
public async Task PostDirAsync(string localDirPath, string serverDir)
{
var sourcePath = Path.Combine("Temp", Guid.NewGuid() + ".zip");
ZipFile.CreateFromDirectory(localDirPath, sourcePath, CompressionLevel.Fastest, true);
var rest = new RestClient("http://localhost:50424/api/File/PostDir");
var req = new RestRequest(Method.POST);
req.AddFile(Path.GetFileName(sourcePath), sourcePath);
req.AddHeader("Content-Type", "multipart/form-data");
req.AddParameter("serverPath", serverDir, ParameterType.QueryString);
var resp = rest.Execute(req);
}
What am I missing or doing wrong?

Resharpe.portable get Twitter request token

Hello i'm doing an xamarin.form application and i'm implementing the twitter login using oauth.
I have problem to get the request_token folowing the link:
https://dev.twitter.com/oauth/reference/post/oauth/request_token
using restsharp.portable for the request POST i arrive at this point:
public async void GetTwitterToken()
{
try
{
TwitterLogin tw = new TwitterLogin();
RestClient client = new RestClient("https://api.twitter.com");
RestRequest request = new RestRequest("/oauth/request_token", Method.POST);
client.Authenticator = OAuth1Authenticator.ForRequestToken(tw.oauth_consumer_key, tw.oauth_consumer_secret);
IRestResponse response = await client.Execute(request);
}
catch (Exception e)
{
}
}
Parameter "response" it's ok but i'don't know how to parse to get token (it's not json).
i have seen this example:
public void GetRequestToken()
{
var client = new RestClient("https://api.twitter.com"); // Note NO /1
client.Authenticator = OAuth1Authenticator.ForRequestToken(
_consumerKey,
_consumerSecret,
"http://markashleybell.com" // Value for the oauth_callback parameter
);
var request = new RestRequest("/oauth/request_token", Method.POST);
var response = client.Execute(request);
var qs = HttpUtility.ParseQueryString(response.Content);
_token = qs["oauth_token"];
_tokenSecret = qs["oauth_token_secret"];
}
But i don't have HttpUtility.ParseQueryString(response.Content) whith xamarin.form framework

wp7 - POST http request with parameters in request body using RestSharp

I am trying to POST parameters through the request, to a service that returns a JSON object. The service works well for android and iOS. I am trying to get this working for wp7. The service requires the content type to be 'application/json' I have pasted the code that sets up the http request below:
var client = new RestClient(baseurl);
var request = new RestRequest();
request.Resource = "login";
request.Method = Method.POST;
request.AddHeader("Accept", "application/json");
request.AddHeader("content-type", "application/json");
request.RequestFormat = DataFormat.Json;
var postData = new Dictionary<string, string>()
{
{"key1",value1},
{"key2",value2}
};
request.AddBody(postData);
client.ExecuteAsync(request, response =>
{
var jsonUser = response.Content;
});
The response error I get from the server is an internal server error. Is anything wrong with the code above. I also tried request.AddParameter method but ended with the same result. The code for that is below:
var client = new RestClient(baseurl);
var request = new RestRequest();
request.Resource = "login";
request.Method = Method.POST;
request.AddHeader("Accept", "application/json");
request.AddHeader("content-type", "application/json");
request.RequestFormat = DataFormat.Json;
var postData = new Dictionary<string, string>()
{
{"key1",value1},
{"key2",value2}
};
var json = JsonConvert.SerializeObject(postData);
request.AddParameter("application/json", json, ParameterType.RequestBody);
client.ExecuteAsync(request, response =>
{
var jsonUser = response.Content;
});
Is there anything that I am doing wrong in either of the cases?

Resources