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'
}
);
}
Related
I'm trying to make a post request with a form data, containing a file and a Json Object.
To perform this, i set the Content-Type to undefined, according to the following post
https://stackoverflow.com/a/25183266/4573767
This causes the browser to set the Content-Type to multipart/form-data
and fill the boundary correctly.
However, on the (springboot) server side, i get this error message :
Resolved exception caused by Handler execution:
org.springframework.web.HttpMediaTypeNotSupportedException: Invalid
mime type "undefined": does not contain '/'
So, it seems that the "undefined" content type is not correctly managed by the browser.
Here is the fetch command, on the client side :
// My document blob
var documentBlob = new Blob([JSON.stringify({ documentName: "toto" })], {
type: "application/json"
});
// My Form data containing a file and the document blob
var formData = new FormData();
formData.append("file", this.state.file);
formData.append("document", documentBlob);
// Fetch command
fetch("/document/", {
method: "POST",
headers: {
"Content-Type": undefined
},
data: formData
}).then(function(response) {
console.log("response!");
});
Here is the server side (spring boot rest controller) :
#RestController
#RequestMapping("/document")
public class DocumentController {
#Autowired
private DocumentRepository documentRepository;
#RequestMapping(value = "/", method = RequestMethod.POST, consumes = { "multipart/form-data" })
public boolean addDocument(#RequestPart("document") Document document, #RequestPart("file") MultipartFile file) {
documentRepository.save(document);
return true;
}
}
"Document" is a simple pojo :
#Entity
public class Document {
private String documentName;
public Document() {
}
public Document(String documentName) {
this.setDocumentName(documentName);
}
public String getDocumentName() {
return documentName;
}
public void setDocumentName(String documentName) {
this.documentName = documentName;
}
}
So, i don't really get if the problem is in the client or server side.
Thanks!
//////////////////////////////
EDIT :
I finally got it working, but using axios instead of fecth:
Here is my finaly spring boot rest controller :
#RequestMapping(value = "/", method = RequestMethod.POST)
public boolean addDocument(#RequestPart("document") Document document, #RequestPart("file") MultipartFile file) {
// Do things!
return true;
}
And my javascript/axios call :
var documentBlob = new Blob([JSON.stringify({ documentName: "test" })], {
type: "application/json"
});
var formData = new FormData();
formData.append("document", documentBlob);
formData.append("file", this.state.file);
axios({
method: "post",
url: "/document/",
data: formData,
config: { headers: { "Content-Type": "multipart/form-data" } }
})
.then(response => {
console.log("it's working!");
console.log(response);
})
.catch(function(error) {
console.log(error);
});
I finally got it working, but using axios instead of fecth.
See the edited original post to see my solution.
I think the issue is in your spring controller request mapping.
You should not have the mapping to / there.
Try this...
#RestController
#RequestMapping("/document")
public class DocumentController {
#Autowired
private DocumentRepository documentRepository;
#RequestMapping(method = RequestMethod.POST, consumes = { "multipart/form-data" })
public boolean addDocument(#RequestPart("properties") Document document, #RequestPart("file") MultipartFile file) {
documentRepository.save(document);
return true;
}
}
Have you tried to make that request with the "multipart/form-data" content type header?
With that mapping method consuming the defined header, your controller won't be able to parse the request without the proper content type.
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.
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)
I'm trying to make an angularjs $http.get request with parameters but it's not working due to syntaxt may be. Can you please
confirm what i'm doing wrong , maybe syntax is wrong in angularjs call or in java api method
$http.get(document.requestPathPrefix + "/home/my-api",
$scope.requestParametersObject
).then(
function(response) {
$scope.output = response.data;
},
function(response) {
$scope.retrieveErrorMssg = "Failed to retrieve required data.";
});
my parameters are like in this image
parameter object for api call
And in java api call like this
#RequestMapping(value = "/my-api", method = RequestMethod.GET)
public ResponseEntity<Collection<MyObjectResponse>> getMyObjResponse(#RequestBody final MyObjectRequest request)
{
Map<Integer,MyObjectResponse> oResponse = new HashMap<>();
try {
//Manipulation and db calls
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return new ResponseEntity<Collection<MyObjectResponse>>(oResponse.values(), HttpStatus.OK);
}
try ,
$http({
url: '/home/my-api',
method: "GET",
headers: {
'Content-type': 'application/json'
},
data: JSON.stringify(request)
}).success(function(data, status, headers, config) {
}).error(function(data, status, headers, config) {
return null;
});
If you are worried about syntax, take a look at this simple example and modify it to your need.
In JS, your http.get call should contain the URL and its parameters if any,
$http.get('getUserInfo',
{
params : {
'userEmail' : 'userEmail'
}
}).then(function(response) {
console.log(response);
});
If you are passing a parameter to the API call, ensure your Java controller or the service has the parameter defined to receive the same. Ideally the parameters should match between the call and the provider
For example, for the above API call, the spring controller should like below,
#RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
public #ResponseBody User getUserInfo(
#RequestParam("userEmail") String userEmail) {
// Do Something
}
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)