How to resolve 400() error when file uploading via REST service - javascript

I have a program (Spring Boot) which is using REST service to upload files to the server or any other given location. But when I use the same service below error happened and below is the problem.
I am getting 400() error without any description when uploading a file via REST service. This application is Spring boot application which use java-script front-end to upload and download files via implemented rest service.
Help to resolve this. your help is appreciated. Thanks.
error is :
below is the code:
JS:
document.getElementById('import2').onclick = function () {
var files = document.getElementById('selectFiles').files;
console.log(files);
if (files.length <= 0) {
return false;
}
//serverUploaded = true;
var form_data = new FormData(files.item(0));
//from new NLP
$.ajax({
type: "POST",
url: "http://localhost:8080/gsta/upload",
processData: false,
contentType: false,
async: false,
cache: false,
data: form_data,
success: function (result) {
//alert(JSON.stringify(result));
//$("#out_lexalytics").html(JSON.stringify(result));
if (result) {
if(result.statusCode == 200)
{
serverUploaded = true;
}
}
}
});
}
REST service:
#PostMapping("/upload")
// If not #RestController, uncomment this
#ResponseBody
public ResponseEntity<?> uploadFile(#RequestParam("data") MultipartFile uploadfile) {
logger.debug("Single file upload!");
if (uploadfile != null && uploadfile.isEmpty()) {
return new ResponseEntity("please select a file!", HttpStatus.OK);
}
try {
saveUploadedFiles(Arrays.asList(uploadfile));
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);
}

I created the same scenario in my local environment with postman like this;
Server side with one small change (#RequestMapping(value = "/upload", method = RequestMethod.POST));
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity<?> uploadFile(#RequestParam("data") MultipartFile uploadfile) {
logger.debug("Single file upload!");
if (uploadfile != null && uploadfile.isEmpty()) {
return new ResponseEntity("please select a file!", HttpStatus.OK);
}
return new ResponseEntity("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);
}
It works.

My assumption: your method saveUploadedFiles throws an IOException.
As you are getting a 400 Bad Request as response, I Think you should debug your
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
Block in order to find out what causes a IOException.

Related

Sending data through controller, in mvc pattern using ajax

Using knockout I am trying to send data, from my UI to the controller. This is the javascript used to send my ajax request(PUT)
var model = new Object();
model.StudentID = "";
model.ActiveProgram = "";
model.ProgramDesc = self.programData();
model.Cohorts = self.associationData();
model.LoadIntent = self.loadIntentData();
model.Francophone = self.frenchData();
model.Gender = self.genderData();
$.ajax({
url: putStudentRegRequirementsUrl,
type: "PUT",
contentType: jsonContentType,
dataType: "json",
data: JSON.stringify(model),
//jsonData:model,
success: function (data) {
$('#notificationHost').notificationCenter('addNotification', { message: "Updated.", type: "info" });
},
error: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.status != 0)
{
$('#notificationHost').notificationCenter('addNotification', { message: "Unable to update registration requirement.", type: "error"});
}
}
});
But when I debug it to see my controller, the string comming in is blank. This is my controller
[HttpPut]
public async Task<JsonResult> UpdateRegistrationRequirementAsync(string regRequirementJson)
{
try
{
var regRequirementModel = JsonConvert.DeserializeObject<RegistrationRequirement>(regRequirementJson);
var response = await ServiceClient.L09PutRegistrationRequirementAsync(CurrentUser.PersonId, regRequirementModel);
return Json(response);
}
catch( Exception ex)
{
Logger.Debug(ex, "Error updating Registration Requirement for user failed.");
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Error updating Registration Requirement.");
}
}
Action will parse parameters from client by its name, so you need to pass parameter with name regRequirementJson contains your json. So change this line
data: JSON.stringify(model)
to
data: { regRequirementJson: JSON.stringify(model) }
and remove contentType: jsonContentType.
Or you can try another way. Since ASP.NET can deserialize json by itself you can keep your js code as is and update your controller to
[HttpPut]
public async Task<JsonResult> UpdateRegistrationRequirementAsync(RegistrationRequirement regRequirementModel )
{
try
{
var response = await ServiceClient.L09PutRegistrationRequirementAsync(CurrentUser.PersonId, regRequirementModel);
return Json(response);
}
catch( Exception ex)
{
Logger.Debug(ex, "Error updating Registration Requirement for user failed.");
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Error updating Registration Requirement.");
}
Since you are sending a "RegistrationRequirement" object then in your controller you can do it this way :
[HttpPut]
public async Task<JsonResult> UpdateRegistrationRequirementAsync(RegistrationRequirement registrationRequirement)
{
try
{
var response = await ServiceClient.L09PutRegistrationRequirementAsync(CurrentUser.PersonId, registrationRequirement);
return Json(response);
}
catch( Exception ex)
{
Logger.Debug(ex, "Error updating Registration Requirement for user failed.");
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Error updating Registration Requirement.");
}
}

Angular JS + Spring MVC: Getting a 406 while trying to download a generated file

I'm trying to download a file that was generated from the database base64 String field. I see that file is created successfully but download fails...
This is my Spring MVC controller method:
#RequestMapping(value = "/download", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Response download(#RequestBody DocumentCaseFile documentCaseFile) throws ServiceLogicException {
return documentCaseFileService.prepareFile(documentCaseFile);
}
Here is the service method:
#Override
public Response prepareFile(DocumentCaseFile documentCaseFile) throws ServiceLogicException {
final String contents = documentCaseFile.getContent();
final String pathAndFileName = "files/" + documentCaseFile.getFilename();
File file = new File(pathAndFileName);
byte[] decodedImg = Base64.getDecoder().decode(contents.getBytes(StandardCharsets.UTF_8));
Path destinationFile = Paths.get(file.getAbsolutePath());
try {
Files.write(destinationFile, decodedImg);
file = destinationFile.getFileName().toFile();
} catch (IOException e) {
e.printStackTrace();
file = null;
}
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM_VALUE)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
.build();
}
And here is the frontend part for the download function:
$scope.downloadFile = function(documentCaseFile) {
$http.post(webserviceUrl + documentCaseFileDownload, documentCaseFile, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/octet-stream'
}
}).then(function successCallback(response) {
console.log('file download response');
console.log(response);
}, function errorCallback(response) {
console.error('file download error');
console.log(response);
});
};
Any help greatly appreciated!
Generally speaking, when you have response.getOutputStream(), you can write anything there. You can pass this output stream as a place to put generated PDF to your generator. Also, if you know what file type you are sending, you can set
response.setContentType("application/pdf");
and you are use into you angular code, you need to change it with fie type
headers: {
'Content-Type': 'application/json',
'Accept': 'application/octet-stream'
}
Turns out produces = MediaType.APPLICATION_OCTET_STREAM_VALUE was causing the problem in the controller, I had to remove it to make the error go away:
#RequestMapping(value = "/download", method = RequestMethod.POST)

How to upload object from JavaScript to Rest API

I have a Rest API:
[HttpPost]
[Route("Services/Image/Upload")]
public string Upload([FromBody]GalleryItem galleryItem)
{
try
{
var appSettings = ConfigurationManager.AppSettings["GalleryPath"].ToString();
using (FileStream fs = new FileStream(appSettings + galleryItem.KeyCode + ".jpg", FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] data = Convert.FromBase64String(galleryItem.Base64);
bw.Write(data);
bw.Close();
}
}
return "OK";
}
catch (Exception ex)
{
return ex.ToString();
}
}
and I call it from my Javascript client like:
var galleryItem = new Object();
galleryItem.Base64 = base64;
galleryItem.KeyCode = '1234';
url = "http://my domain name/api/Services/Image/Upload";
$.ajax({
type: 'POST',
url: url,
data: JSON.stringify(galleryItem),
contentType: 'application/json; charset=utf-8',
dataType: 'text/plain',
success: function (msg) {
alert('Image saved successfully !');
},
error: function (jqXHR, textStatus, err) {
$('#error').html('Error: ' + err);
}
});
my model:
public class GalleryItem
{
public string Base64 { get; set; }
public string KeyCode { get; set; }
}
I a testing this via a mobile device as I am taking image from camera to send up.
Nothing appears to happen? I just 'Error: error'?
thanks
ADDITIONAL:
After porting to a test script (wished I had done that sooner) I found the error is this:
net::ERR_NAME_NOT_RESOLVED
Though why I am unsure as I am calling another method from that api with no issues
Solved!
Thank God!
I changed the url to relative:
url = "/api/Services/Image/Upload";
without prefixing with domain name.
it must have got confused and thought it needed cors? (guess here)

How to print receipt without print dialog box in client side

I want print receipt in client side without print dialog box, i am using mvc this is my solution to achieve my problem.
EPSON printer was installed in my system.This solution is working when host in my local iis but its not work when host in server and accessing from my local system getting "An error occurred while processing your request" error. In server no printer is installed.
$.ajax({
type: "POST",
url: '../Service/print',
cache: false,
data: { iprintData: printData, iprinterName: sPrinterName },
success: function (data) {
// alert('print Send Successfully');
},
error: function (ex) {
alert(ex.responseText);
// alert('error while Seding print');
}
});
this is my code in controller
public JsonResult print(string iprintData, string iprinterName)
{
Boolean bflag = false;
System.Web.HttpContext.Current.Session["_printData"] = iprintData;
PrintDocument printDocument = new PrintDocument();
printDocument.PrintController = new StandardPrintController();
printDocument.PrintPage += PrintDocumentOnPrintPage;
printDocument.PrinterSettings.PrinterName = iprinterName;
//printFont = new System.Drawing.Font("Arial", 10);
printDocument.Print();
bflag = true;
return Json(bflag, JsonRequestBehavior.AllowGet);
}
public static Image resizeImage(Image image, int new_height, int new_width)
{
Bitmap new_image = new Bitmap(new_height, new_width);
Graphics g = Graphics.FromImage((Image)new_image);
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, new_width, new_height);
return new_image;
}
private void PrintDocumentOnPrintPage(object sender, PrintPageEventArgs e)
{
string printstring = System.Web.HttpContext.Current.Session["_printData"].ToString();
string path = HttpContext.Server.MapPath("~/content/Images/logo.png");
System.Drawing.Image img = Image.FromFile(path);
//img = resizeImage(img, 80, 60);
e.Graphics.DrawImage(img, 6, 100);
e.Graphics.DrawString(printstring, new System.Drawing.Font("ronnia", 9), Brushes.Black, 10, 150);
}
can any one help me from this ?
first you have to write windows service that contain HttpListener.
write your printing code inside the service
Install the service in client machine
call that service using ajax like below.
function PrintReceipt() {
var PrintData = JSON.parse($("#receiptData").html())
if (PrintData.length > 0) {
$.ajax({
type: "POST",
url: "http://localhost:41963/printOrder",
data: JSON.stringify({ "PrintData": PrintData }), //reciept data
crossDomain: true,
success: function (response) {
},
error: function () {
}
});
}
}
set System.Drawing.dll property
Copy Local=true

Retrieve JSON not working with AngularJS and GSON

I have a RESTapi with the following methode:
#Path("/banksummary")
public class BankSummaryRestService {
Database db = new DatabaseAccessOutput();
#GET
#Path("/")
public String printMessage() throws Exception {
Summary result;
try {
result = db.getBankSummary();
}
catch (Exception e) {
throw e;
}
Gson gson = new Gson();
String json = gson.toJson(result);
return json;
}
}
When I go to localhost:8080/html5/api/1.0/banksummary I see the output.
In my AngularJS project I have the following code:
In service.js:
dashboardAPI.getBankSummary = function() {
return $http(
{
method: 'GET',
url: 'localhost:8080/html5/api/1.0/banksummary'
}
);
}
In the controller:
dashboardAPIService.getBankSummary().success(function (response) {
$scope.summary = response;
});
When I used a local json file it worked, but now I use the URL to the RESTapi (local file had to be replaced by the RESTapi) and I get the following error:
XMLHttpRequest cannot load localhost:8080/html5/api/1.0/banksummary. Cross origin requests are only supported for HTTP. angular.min.js:76
Error: A network error occurred.
Anyone that knows what I'm doing wrong?
You need to specify the protocol (in this case, http) in your URL:
dashboardAPI.getBankSummary = function() {
return $http(
{
method: 'GET',
url: 'http://localhost:8080/html5/api/1.0/banksummary'
}
);
}

Categories

Resources