Sending image in base64 to Java webserver, convert and save it - java

I have a website with an ongoing webcam stream which should send snapshots of the video stream to my own Java webserver. The snapshot generating and displaying functionality works perfectly on the website. I want to send the snapshot with a jQuery AJAX POST request to my webserver which looks like that:
$.ajax({
type: 'POST',
url: servicePath + "upload",
contentType: 'multipart/form-data',
xhrFields: {withCredentials: false},
headers: {},
data: hidden_canvas.toDataURL('image/png'),
success: function(data, status, xhttp) {
alert(data);
},
error: function() {
alert("Error uploading snapshot file to server!");
}
});
As I mentioned, displaying the hidden_canvas.toDataURL('image/png') inserted in a src attribute of an <img> works perfectly, so it is definitely valid.
My service on the webserver looks as follows:
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadPicture(byte[] imageBytes) {
String uploadedFileLocation = UPLOAD_FOLDER + "test.png";
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
out.write(imageBytes);
out.flush();
out.close();
} catch (IOException e) {
return Response.status(500).entity("Can not save file<br>" + e.toString()).build();
}
return Response.status(200).entity("success").build();
}
Test.png is created successfully but not a valid png, when I open it, it does not display at all. And the file on the server looks as follows:
What did I miss? Would there be an alternative way to process the image?
Here's my takeSnapshot method. How could I send the file without the toDataURL()? And what for param would I have to expect then on the server side?
function generateSnapshot() {
var video = document.querySelector('#camera-stream');
var hidden_canvas = document.querySelector('#canvas');
var context = hidden_canvas.getContext('2d');
var width = video.videoWidth;
var height = video.videoHeight;
if (width && height) {
hidden_canvas.width = width;
hidden_canvas.height = height;
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 0, 0, width, height);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
}

I finally could make it work. The toBlob suggestion from Kayaman put me on the right track. But I was not able to send the blob as expected, I had to put it into a FormData and thus had to adjust my webservice. The solution looks as follows:
Website Javascript code:
hidden_canvas.toBlob(function(blob) {
var fd = new FormData();
fd.append('fileName', 'testBlob.png');
fd.append('data', blob);
sendAJAXFileUploadRequest(fd);
},'image/png');
function sendAJAXFileUploadRequest(formData) {
$.ajax({
type: 'POST',
url: servicePath + "upload",
xhrFields: {withCredentials: false},
headers: {},
data: formData,
processData: false,
contentType: false,
success: function(data, status, xhttp) {
alert(data);
},
error: function() {
alert("Error uploading snapshot file to server!");
}
});
}
And the Java Webservice:
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadPicture(#FormDataParam("data") byte[] imageBytes, #FormDataParam("fileName") String fileName) {
String uploadedFileLocation = UPLOAD_FOLDER + fileName;
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
out.write(imageBytes);
out.flush();
out.close();
} catch (IOException e) {
logger.severe("Can not save file (file location: " + uploadedFileLocation + ")");
return Response.status(500).entity("Can not save file<br>" + e.toString()).build();
}
return Response.status(200).entity("success").build();
}

Related

Edit files online using Office 365 using WOPI not working - Java

I have a requirement where from my application I have to edit files using office 365. I have used WOPI and it was working fine before, but now I'm getting the following error.
When I contacted the support team, they said WOPI CheckFileInfo is not called, so I explicitly called still the issue persists.
Below is my code,
function submit(docId, type) {
var WOPISrc = "WOPISrc=https://" + host +"/wopi/files/" + docId;
if (type == 'word') {
$('#office_form_online').attr('action', 'https://word-edit.officeapps.live.com/we/wordeditorframe.aspx?edit=1&ui=en-US&rs=en-US&IsLicensedUser=1&hid=1234&sc=edit_form&' + WOPISrc);
} else if (type == 'excel') {
$('#office_form_online').attr('action', 'https://excel.officeapps.live.com/x/_layouts/xlviewerinternal.aspx?edit=1&ui=en-US&rs=en-US&IsLicensedUser=1&hid=1234&sc=edit_form&' + WOPISrc);
} else if (type == 'powerpoint') {
$('#office_form_online').attr('action', 'https://powerpoint.officeapps.live.com/p/PowerPointFrame.aspx?PowerPointView=EditView&ui=en-US&rs=en-US&IsLicensedUser=1&hid=1234&sc=edit_form&' + WOPISrc);
} else if (type == 'pdf') {
$('#office_form_online').attr('action', 'https://word-view.officeapps.live.com/wv/wordviewerframe.aspx?PdfMode=1&ui=en-US&rs=en-US&IsLicensedUser=1&hid=1234&sc=edit_form&' + WOPISrc);
} else {
return false;
}
var promise = createWOPIToken(docId);
promise.success(function (data) {
$.ajax({
url: "https://" + host + "/wopi/files/" + docId,
type: "GET",
data: {
access_token: data.token
},
async: false,
dataType: "json",
contentType: "application/json; charset=utf-8",
error: function (jqXHR, textStatus, errorThrown) {
return '';
},
success: function (data1) {
console.log(data1);
$.ajax({
url: "https://" + host + "/wopi/files/" + docId + "/content",
type: "GET",
data: {
access_token: data.token
},
async: false,
dataType: "json",
contentType: "application/json; charset=utf-8",
error: function (jqXHR, textStatus, errorThrown) {
return -1;
},
success: function (contents) {
$('#office_access_token_online').val(data.token);
$('#office_access_token_ttl_online').val(0);
var frameholder = document.getElementById('frameholder_online');
$(frameholder).show();
closeiFrame();
var office_frame = document.createElement('iframe');
office_frame.src = 'https://"+ host + "/wopi/files/" ' + docId + "?access_token="+data.token;
office_frame.name = 'office_frame_online';
office_frame.id = 'office_frame_online';
office_frame.title = 'Office Online Frame';
office_frame.setAttribute('allowfullscreen', 'true');
office_frame.setAttribute('sandbox',
'allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation allow-popups-to-escape-sandbox');
frameholder.appendChild(office_frame);
document.getElementById('office_form_online').submit();
showCloseButton();
}
});
}
});
});
}
Java Code
#Override
#GET
#Path("/files/{fileId}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response checkFileInfo(
#NotNull #PathParam("fileId") Integer fileId,
#NotNull #QueryParam("access_token") String access_token) {
return Response.ok().entity(fileInfo).build();
}
}
#Override
#GET
#Path("/files/{fileId}/content")
#Produces(MediaType.APPLICATION_JSON)
public Response getFile(
#NotEmpty #PathParam("fileId") Integer fileId,
#QueryParam("access_token") String access_token) {
byte[] data = new byte[(int) content().length()];
DataInputStream dataIs = new DataInputStream(content.getBinaryStream());
dataIs.readFully(data);
return Response.ok(new ByteArrayInputStream(data)).build();
}
#Override
#POST
#Path("/files/{fileId}/contents")
#Transactional
public Response putFile(#PathParam("fileId") Integer fileId,
#QueryParam("access_token") String access_token, byte[] bytes) {
save(BlobProxy.generateProxy(SecurityWrapper.encrypt(bytes)));
return Response.ok().build();
}
The API calls are returning responses but it's not opening files.
EDIT
When I try hitting the below URL (which is used to open files online), without any source, still it shows as Service Unavailable.
https://word-edit.officeapps.live.com/we/wordeditorframe.aspx?
Is it because of it, that my code isn't working? And in the test server, it's a different error, we ran into a problem.
And this is the console error
Any help is appreciated.
Thank you.

Downloading a file using AJAX GET from Spring Service

I'm trying to implement a Service that automatically starts a download with the requested file.
This is my AJAX call:
function downloadFile(fileName) {
$.ajax({
url : SERVICE_URI + "files/" + fileName,
contentType : 'application/json',
type : 'GET',
success : function (data)
{
alert("done!");
},
error: function (error) {
console.log(error);
}
});
}
and this is my Spring Service method GET:
#RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
public void getFile(#PathVariable("file_name") String fileName,
HttpServletResponse response) {
try {
// get your file as InputStream
FileInputStream fis = new FileInputStream( fileName + ".csv" );
InputStream is = fis;
// copy it to response's OutputStream
ByteStreams.copy(is, response.getOutputStream());
response.setContentType("text/csv");
response.flushBuffer();
} catch (IOException ex) {
throw new RuntimeException("IOError writing file to output stream");
}
}
When my client requests the existing file from the server, the AJAX success() method is executed but the file is not even downloading. Am I doing anything wrong?
Don't use ajax, just set window.location.href to the url of the file and set the http content disposition header in your server script to force the browser to save the file.
function downloadFile(fileName) {
window.location.href = SERVICE_URI + "files/" + fileName;
}

How to send file back to client browser from Java after jQuery.post()

I need help with sending xlsx-file from the server back to the client
This is how it worked BEFORE:
JavaScript (click #export_xls button):
export_xls: function(event) {
window.location = ... + this.workspace.query.id + "/export/xls";
}
Java (create xls-file using Apache POI API):
#GET
#Produces({"application/vnd.ms-excel" })
#Path("/{queryname}/export/xls/{format}")
public Response getQueryExcelExport(
#PathParam("queryname") String queryName,
#PathParam("format") #DefaultValue("flattened") String format){
// ...
try {
byte[] doc = olapQueryService.getExport(queryName,"xls","flat"); // file
String name = "file.xls";
return Response.ok(doc, MediaType.APPLICATION_OCTET_STREAM).header(
"content-disposition",
"attachment; filename = " + name).header(
"content-length",doc.length).build();
}
catch (Exception e) {
log.error("Cannot get excel for query (" + queryName + ")",e);
return Response.serverError().build();
}
}
And it worked fine, but now i need to send some data from javascript to the java, then java process it and create xlsx
So, i use ajax to send that data (in json format)...
export_xls: function(event) {
var data = this.workspace.query.result.lastresult();
var url = ... + this.workspace.query.id + "/testexportxls";
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(data),
async: false,
contentType: "application/json"
});
},
...and create my file in java (almost like it was before):
#POST
#Produces({"application/vnd.ms-excel" })
#Consumes(MediaType.APPLICATION_JSON)
#Path("/{queryname}/testexportxls")
public Response setQueryExcelExport(final Object jsonData)
{
Workbook wb = MyFileBuilder.getFile(jsonData);
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
wb.write(bout);
byte[] doc = bout.toByteArray();
String name = "file.xlsx";
return Response.ok(doc, MediaType.APPLICATION_OCTET_STREAM).header(
"content-disposition",
"attachment; filename = " + name).header(
"content-length",doc.length).build();
}
catch (Exception e){
log.error("Error while xlsx-file creating. Exception message: ",e);
return Response.serverError().build();
}
}
But i can't get that file now, because of the ajax, i think.
Do you know some quick solution, with minimum code edits?
Unfortunately, I almost know nothing about Response, or some HttpServletResponse and stuff like that =/
Thank you for your time.
If you were to define a callback function on success, wouldn't that function be able to handle the file?
Seems not, so I'll have a second try: put the JSON in a hidden form input, and POST the form?

jQuery.ajax servlet return a file [duplicate]

This question already has an answer here:
How to download file from httpServlet with Jquery?
(1 answer)
Closed 5 years ago.
I'm pretty new to jQuery and ajax and i have a question.
In a jsp I call
function downloadDocument(documentId){
var action = "attachment.do";
var method = "downloadDocument";
var url = action + "?actionType="+method+"&documentId=" + documentId;
$.ajax({
url: url,
dataType: "json",
type: 'POST',
success: function(data){
alert("downloaded!");
},
error: function (request, status, error) {
alert(request.responseText);
}
});
then in the servlet I do
public void downloadDocument(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws IOException{
AttachmentActionForm form = (AttachmentActionForm)actionForm;
ServletOutputStream out = response.getOutputStream();
try{
// Get the downloadFileName, the name of the file when it will be downloaded by user
String downloadFileName = "hello.txt";
String mimetype = "application/x-download"
// Get the byte stream of the file
FileInputStream in = new FileInputStream(Global.ATTACHMENTS_SHARED_FOLDER_PATH + downloadFileName);
// Print out the byte stream
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
response.addHeader("Content-Disposition", "attachment; filename="+downloadFileName);
response.setHeader("Content-Length", Integer.toString(length));
response.setContentType(mimetype);
in.close();
}
catch(Exception e){
response.setContentType("text/text;charset=utf-8");
response.setHeader("cache-control", "no-cache");
System.out.println(e.getMessage());
out.println(e.getMessage());
}finally{
out.flush();
}
}
But in the ajax function, I never get a success, all the time I get the error message, even if the message is composed by the string inside of the file. What can I do?
Remove your dataType: "json", options and you will see some debug informations.
By the way, there is a jQuery option that meet you need:
$.fileDownload('some/file.pdf')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); })
Taken from this answer: https://stackoverflow.com/a/9970672/1420186
EDIT:
Your JSP
function downloadDocument(documentId){
var action = "attachment.do";
var method = "downloadDocument";
var url = action + "?actionType="+method+"&documentId=" + documentId;
$.ajax({
url: url,
dataType: "text", // Change dataType to "text"
type: 'POST',
success: function(data){
if (data == "FAIL") {
alert("File not found!");
} else {
window.location.href = data; // Download the file
}
},
error: function (request, status, error) {
alert("The request failed: " + request.responseText);
}
});
}
In your Servlet, if the file is not exists, just return a "FAIL" string, else return the file URL.
Hope that helps.
dont use Ajax call use //use hidden form approach
<form action='../servletname' method='POST' id='formid'>
<input type='hidden' value='' name='name' id='id'/>
<input type='hidden' value=' ' name='name' id='id' />
</form>
on click of button submit form
$('#formid').submit();
in servlet
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=filnemae.fileformat");
ServletOutputStream out = res.getOutputStream();
write on ouput stream then close or flush
if you are sending large data through post update postsize in server.xml

Ajax call to Stripes framework in Java results in an empty request body

Environment: Eclipse running Tomcat v7.0, working with the Stripes framework for Java, and submitting to the service via a JQuery ajax call.
The Javascript:
jQuery( function(){
jQuery('#testForm').submit( function(e) {
e.preventDefault();
var dataString = jQuery('#testInput').val(); // Pulled from a textarea for testing purposes.
var urlString = jQuery('#urlDropdown').val(); // Pulled from a dropdown for testing purposes.
if( (jQuery('#urlId') != "" ) &&
(!isNaN(parseInt( jQuery('#urlId').val() )) ) ){ // Pulled from an input type=text for testing purposes.
urlString += '?id=' + parseInt( jQuery('#urlId').val() );
}
alert("urlString: " + urlString);
jQuery.ajax({
type: "POST",
url: urlString,
data: dataString,
dataType: 'json',
success: function( returnData ) {
jQuery('#content').html(JSON.stringify(returnData));
},
fail: function( returnData ) {
alert("FAIL");
}
});
});
});
The Stripes Interceptor:
#Before(stages=LifecycleStage.BindingAndValidation, on={"setClient"})
private Resolution intercept() {
String rbody = getRequestBody();
log.info("BODY: " + rbody);
this.setBody( rbody );
return null;
}
And the getRequestBody method being used:
protected String getRequestBody(){
StringBuffer body = new StringBuffer();
String line = null;
try {
BufferedReader reader = getContext().getRequest().getReader();
while ((line = reader.readLine()) != null)
body.append(line);
} catch (Exception e) {
log.error("Buffered Reader Failed", e);
e.printStackTrace();
}
log.info("BODY: " + body.toString());
return body.toString();
}
I am using Firebug to test the input, and the post body of the request is indeed filled with meaty json.
The log.info calls there output a completely empty string. If I call up the getContentLength() on the getRequest, it tells me that the content has the appropriate number of characters. But the content itself comes out as null.
I am 99.99% sure that nowhere else in the code is the Request body being consumed. At the moment, this is my only action file in the Stripes framework, as I've removed every single other file.
Somehow, the request body is completely empty. It should be full of meaty json. Help me, Stack Overflow, you're my only hope!
Thanks to the fine people on the Stripes IRC channel, I have an answer! I needed to add in contentType: "application/json", as so:
jQuery.ajax({
type: "POST",
url: urlString,
contentType: "application/json",
data: dataString,
dataType: 'json',
processData: false,
success: function( returnData ) {
jQuery('#content').html(JSON.stringify(returnData));
},
fail: function( returnData ) {
alert("FAIL");
}
});

Categories