Angular js file upload to server via REST call - java

data passed in uploadData function contains below value:
lastModified:1478845421494
lastModifiedDate:Fri Nov 11 2016 11:53:41 GMT+0530 (India Standard Time)
name:"u_ex150626.log"
size:2022067
type:""
webkitRelativePath:""
__proto__:File
In service.js:
function($http, $q) {
return {
uploadData : function(baseUrl, data) {
var fd = new FormData();
/*for(var key in data)
fd.append(key,data[key]);*/
fd.append("file", data);
console.log('fd:' + fd);
var name="Meenu";
return $http.post(baseUrl+'/data/fileupload', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
}).then(
function successCallback(response){
alert('Response: '+response.data);
},function errCallback(errResponse){
alert('Error: '+errResponse.data);
alert('Error: '+errResponse.status);
});
},
}
}
In controller.java:
#RequestMapping(value = "/data/fileupload", method = RequestMethod.POST)
#ResponseBody
public String postFile(#RequestParam(value = "file",required=false) MultipartFile file) {
try {
System.out.println("name = " + file);
} catch (Exception e) {
e.printStackTrace();
}
return "OK";
}
I am getting null value for 'file'. Please let me know how can we receive the file from http request in controller.java.

Related

Spring Boot - Request method 'POST' not supported to upload file

Front: Angular2+
Back: Java15 Spring Boot
DataBase: MySql
I take all examples for upload files in database form in byte[]. with a complex object with file by attribute.
I try desperately to upload an image file on my database so I try to create post API rest by I have error
I'm take
o.s.web.servlet.PageNotFound : Request method 'POST' not supported
#PostMapping(value = "/Ninja/image/")
public ResponseEntity<ResponseMessage> saveNinjaImage(#RequestParam("file") MultipartFile file) {
String message = "";
try {
Iterable<Syndic> lstN= NinjaRepository.findAll();
if(lstN.iterator().hasNext()) {
Ninja s = lstN.iterator().next();
s.setPicture(file.getBytes());
logger.info(s.toString());
}
} catch(Exception e) {
//return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
logger.info(e.toString());
}
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
}
//service
public postNinja(file: File) {
const formData: FormData = new FormData();
formData.append('file', file);
const req = new HttpRequest('POST', `${this.host}/Ninja/image`, formData, {
headers: this.headers,
reportProgress: true,
responseType: 'json'
});
return this.http.request(req);
}
/* ts */
public onSave() {
this.frontDynamic.submitted = true;
if (this.frontDynamic.updateNinja.invalid) {
return;
} else {
const formValue = this.frontDynamic.updateNinja.value;
const newNinja = new Ninja(formValue['nom']);
newNinja.address = formValue['adresse'];
newNinja.description = formValue['description'];
newNinja.website = formValue['site'];
this.ninjaService.putNinja(newNinja,formValue['image']).subscribe(response => {},
error => {console.log(error);}
,
()=>{
this.ninjaService.postNinja(formValue['image']).subscribe(
event => {},
err => {});
);
}
}

CKEditor 5 upload image, What information does the upload image return?

This is web code:
DecoupledEditor
.create( document.querySelector( '#webDetails' ),{
language: 'zh-cn',
image: {
toolbar: [ 'imageTextAlternative' ],
styles: [ 'full', 'side' ]
},
ckfinder: {
uploadUrl: '<%=WEBPATH%>/platform/updateMaterial'
}
} )
.then( editor => {
const toolbarContainer = document.querySelector( '#toolbar-webDetails' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
} )
This is Spring controller:
#PostMapping("updateMaterial")
#ResponseBody
public String updateMaterial(#RequestParam("upload") MultipartFile file, HttpServletRequest request){
String trueFileName = null;
String realPath = null;
try {
realPath = request.getSession().getServletContext().getRealPath("/upload");
System.out.println(realPath);
trueFileName = uploadImg(realPath, file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return "{\"default\":\"" + realPath + File.separator + trueFileName + "\"}";
}
Here I return the address of the image on disk.
It is json String style. I want CKEditor 5 api to return the information, but still failure.
What do I need to return in the background to succeed, or am I missing the step?
thank you.
There are many people asking this question, but none of them have a clear solution. Finally, I found it. My code is as follows.
class UploadAdapter {
constructor(loader) {
this.loader = loader;
}
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('upload', this.loader.file);
data.append('allowSize', 10);//允许图片上传的大小/兆
$.ajax({
url: 'loadImage',
type: 'POST',
data: data,
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
if (data.res) {
resolve({
default: data.url
});
} else {
reject(data.msg);
}
}
});
});
}
abort() {
}
}
DecoupledEditor
.create( document.querySelector( '#b' ), {
language:"zh-cn"
})
.then( editor => {
const toolbarContainer = document.querySelector( '#a' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
// This place loads the adapter.
editor.plugins.get('FileRepository').createUploadAdapter = (loader)=>{
return new UploadAdapter(loader);
};
} )
.catch( error => {
console.error( error );
} );

Cant access success function when call recursive ajax

I'm building a system which has push notification feature and use Jersey to create API.
I read an article about comet approach and end up with the following code:
Index.js
function checkExamNotification() {
$.ajax({
url: contextPath + '/api/notification/checkExamNotification',
type: 'get',
data: {
accountId: accountId,
sessionId: sessionId
},
success: function (res) {
console.log("success");
displayNumberOfNotification();
checkExamNotification();
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus === "timeout") {
checkExamNotification();
}
}
});
}
$(document).ready(function () {
$.ajaxSetup({
timeout: 1000*60*3
});
checkExamNotification();
});
Check exam notification API
#GET
#Path("/checkExamNotification")
public Response checkExamNotification(#QueryParam("accountId") int accountId, #QueryParam("sessionId") String sessionId) throws InterruptedException {
if (memCachedClient.checkSession(sessionId, accountId)) {
while (!examNotificationQueue.hasItems()) {
Thread.sleep(5000);
}
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamId());
ExamEntity exam = examDAO.findById(examNotificationQueueItemModel.getExamId());
NotificationEntity notification = notificationDAO.findByExamId(exam.getExamid());
notification.setSend(1);
notificationDAO.getEntityManager().getTransaction().begin();
notificationDAO.update(notification);
notificationDAO.getEntityManager().getTransaction().commit();
LOGGER.info("[END]");
String result = gson.toJson(examNotificationQueueItemModel);
return Response.status(200).entity(result).build();
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
Thread.sleep(5000);
checkExamNotification(accountId, sessionId);
}
}
return Response.status(200).entity(gson.toJson("timeout")).build();
}
From my debug, the API did finish return but the success event SOMETIMES didn't fire.
Yes, sometimes console log success but sometimes it doesn't.
Can anybody explain to me this case?
Thanks in advance. Any help would be appreciated.
Ok after following #peeskillet comment. Here is my finally code.
Check exam notification API
#GET
#Produces(SseFeature.SERVER_SENT_EVENTS)
#Path("/checkExamNotification")
public EventOutput checkExamNotification(#QueryParam("accountId") final int accountId, #QueryParam("sessionId") final String sessionId) {
final EventOutput eventOutput = new EventOutput();
if (memCachedClient.checkSession(sessionId, accountId)) {
new Thread(new Runnable() {
public void run() {
try {
if (examNotificationQueue.hasItems()) {
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamName());
String result = gson.toJson(examNotificationQueueItemModel);
final OutboundEvent.Builder eventBuilder
= new OutboundEvent.Builder();
eventBuilder.data(result);
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
LOGGER.info("[END]");
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
}
}
} catch (IOException e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
}
return eventOutput;
}
Index.js
function checkExamNotification() {
var url = contextPath + '/api/notification/checkExamNotification?accountId=' + accountId + '&sessionId=' + sessionId;
var source = new EventSource(url);
source.onmessage = function (event) {
displayNumberOfNotification();
};
}

File download/save from a Jersey rest api call using ANGULARJS . file is attached with response as "Content-Disposition"

I am new to angular .. I hava java rest api which return CSV file in response as attachment as | "Content-Disposition", "attachment; filename=" | content-type :application/octet-stream
Now when i am calling this api from AngularJS using $http i am getting response.data ="" (blank)
I am using basic authorisation for security so I have to pass Header while calling calling API so can't use link click or new window open fro CSV download.
to test when i removed authorisation and hit the url in browser then CSV file is being downloaded.so no issue at server side .
I need help at angularjs side to download CSV file from web api response as attachment.
Here is my Java API Code
public class ServiceAPI {
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFileAsCSVFile(){
byte[] file=null;
try {
ArrayList<> List=new ArrayList<>();// data retrieved from DB
if(null != List){
file=convertJsonToCSV(new Gson().toJson(List));
}
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Response.ok(getBytes(file),MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=" + "FileName.csv").build();
}
}
and Angular code :
app.controller('review', ['$scope', '$http', function ($scope, $http){
$scope.fromDate = new Date();
$scope.toDate = new Date();
$scope.minDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.maxDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.reviews = json;
function openSaveAsDialog(filename, content, mediaType) {
var blob = new Blob([content], {type: mediaType});
saveAs(blob, filename);
}
function callApi(url) {
// var dat=apiFactory.getServiceData(url);
// console.log(dat);
// apiFactory.getServiceData(url);
var responseType='arraybuffer';
var expectedMediaType='application/octet-stream';
$http.get(url, {
headers: {
accept: expectedMediaType
},
responseType:responseType,
cache: true,
transformResponse: function (data) {
var pdf;
if (data) {
pdf = new Blob([data], {
type: expectedMediaType
});
}
return {
response: pdf
};
}
}).then(function (data,status,headers) {
var filename='Preview.csv',
octetStreamMime = "application/octet-stream",
contentType;
headers = data.headers();
contentType = headers["content-type"] || octetStreamMime;
// openSaveAsDialog(filename, response.data, expectedMediaType);
if (navigator.msSaveBlob) {
var blob = new Blob([data], { type: contentType });
navigator.msSaveBlob(blob, filename);
} else {
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
// Try to use a download link
var link = document.createElement("a");
if ("download" in link) {
// Prepare a blob URL
var blob = new Blob([data.data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
} else {
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
$window.location = url;
}
}
}
});
};
$scope.submit = function (fromDate, toDate) {
$scope.url = API_url;
var resp =callApi(($scope.url).split(" ").join("%20"));
console.log(resp);
};
},
]);
I have an example with spring MVC instead of JAX-RS (Jersey)
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
Angularjs controler:
$scope.downloadCsv = function () {
console.log("downloadCsv");
var fileName = "test.csv";
var a = document.createElement("a");
document.body.appendChild(a);
XxxxxxServiceCSV.downloadCsv().then(function (result) {
console.log("downloadCsv callback");
var file = new Blob([result.data], {type: 'application/csv'});
var fileURL = URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
Angularjs services:
angular.module('xxxxxxxxApp')
.factory('XxxxxxServiceCSV', function ($http) {
return {
downloadCsv: function () {
return $http.get('api/downloadCSV', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java code JAX-RS(spring MVC):
#RequestMapping(value = "/downloadCSV", method = RequestMethod.GET, produces = "application/csv")
public void demo(HttpServletResponse response) throws IOException {
List<String> names = new ArrayList<String>();
names.add("First Name");
names.add("Second Name");
names.add("Third Name");
names.add("Fourth Name");
BufferedWriter writer = new BufferedWriter(response.getWriter());
try {
response.setHeader("Content-Disposition", "attachment; filename=\"test.csv\"");
for (String name : names) {
writer.write(name);
writer.write(",");
}
writer.newLine();
} catch (IOException ex) {
} finally {
writer.flush();
writer.close();
}
}

Display exception's message from Controller MVC in the jsp page

StudentController - here is my controller class that returns exceptions and i want to handle and display these in jsp
#RequestMapping(value = RequestURL.ADD_STUDENT, method = RequestMethod.POST)
#ResponseBody
public void addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
User user = new User(addStudentRequest.getUsername(),
addStudentRequest.getPassword(), Role.ROLE_STUDENT);
userService.add(user);
user = userService.findByUsername(addStudentRequest.getUsername());
int userId = user.getId();
try {
int groupId = studentGroupService
.getIdByGroupNumber(addStudentRequest.getGroup());
int specializationId = specializationService
.getIdByName(addStudentRequest.getSpecialization());
Student student = new Student(userId, specializationId,
addStudentRequest.getName(),
addStudentRequest.getRegistrationNumber(), groupId,
addStudentRequest.getYear());
studentService.add(student);
} catch (StudentGroupNumberNotFoundException e) {
throw new StudentGroupNumberNotFoundException(e.getMessage());
} catch (SpecializationNotFoundException e) {
throw new SpecializationNotFoundException (e.getMessage());
}
}
student.jsp - jsp page for student
function addStudent() {
var username = $('#modalStudentUsername').val();
var password = $('#modalStudentPassword').val();
var name = $('#modalStudentName').val();
var registrationNumber = $('#modalStudentRegistrationNumber').val();
var group = $('#modalStudentGroup').val();
var year = $('#modalStudentYear').val();
var specialization = $('#modalStudentSpecializationId').val();
var data = '{ "username" : "' + username + '", "password": "'
+ password + '", "name":"' + name
+ '","registrationNumber": "' + registrationNumber + '" , "specialization": "' + specialization
+ '","group": "' + group+'", "year": " ' + year + '" }';
var token = $('#csrfToken').val();
var header = $('#csrfHeader').val();
$.ajax({
type : "POST",
url : "student/add",
contentType : 'application/json',
data : data,
beforeSend : function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader(header, token);
},
success : function(data, status, xhr) {
alert("Success!");
},
error : function(xhr, status, errorThrown) {
alert("Error!");
},
});
}
I want to display in the alert from ajax the exception's message from controller. Could anyone help me? Thanks!
Change the method return type from void to String & give a call to xhr.responseText in alert() just like below:-
Change In Controller:
#ResponseBody
public void addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
// business logic
}
to
#ResponseBody
public String addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
// business logic
}
Change In JavaScript:
function addStudent() {
// ...
$.ajax({
type : "POST",
url : "student/add",
contentType : 'application/json',
data : data,
beforeSend : function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader(header, token);
},
success : function(data, status, xhr) {
alert(xhr.responseText);
},
error : function(xhr, status, errorThrown) {
alert(xhr.responseText);
},
});
}

Categories

Resources