Hi I want to display server side image dynamically in browser using ajax.
but images is not coming.
i have checked the server code in debugging mode its working fine but not sure about client code.
readyState coming as 4 but image is not getting displayed.
Server code :
File f = new File("D:\\mapping events\\Camping\\"+(String) request.getParameter("imageName")+"\\"+"01.jpg");
DataInputStream dis = new DataInputStream(new FileInputStream(f));
byte[] barray = new byte[(int) f.length()];
try
{
dis.readFully(barray); // now the array contains the image
}
catch (Exception e)
{
barray = null;
}
finally
{
dis.close( );
}
sos.write(barray); // send the byte array to client
System.out.println(barray);
sos.close();
Ajax code :
$.ajax({
url: 'GetCampingImages',
type: 'POST',
data:{
imageName:allData[0]
},
cache: true,
dataType: 'json',
success: function(jqXHR)
{
if(jqXHR)
{
if (jqXHR.readyState == 4) {
$('#dynamicCamping01').html('<img src="data:image/jpeg;'+jqXHR.reresponseText+'"/> ');
$('#dynamicCampingDesc01').html("<h3>"+allData[0]+"</h3>");
}
}
else
{
alert("Something went wrong while retriving events");
}
},
error: function(jqXHR)
{
console.log('ERRORS in server: ' );
}
You should encode the binary data using base64, and use the scheme: "data:image/jpeg;base64,...". Directly sending data bytes is not a good idea for jpeg files.
Related
In my application a pdf report only opens in print preview which allows user to directly print the pdf document. Now i want to automate this to verify the pdf content.
I have got the pdf content through an api which is in base64 [did split to get only data], i tried converting to byte array after decoding but it only prints junk characters.[byte array to string]
Now i have converted this data into ByteBuffer and want this to write in pdf.
ByteBuffer decodedBytes = new BASE64Decoder().decodeBufferToByteBuffer(
new String(base64split2[1].substring(0, base64split2[1].length() - 1))
);
Can someone tell me how do i convert this decodedBytes of ByteBuffer to pdf.
Thanks
byte[] decodedBytes = new BASE64Decoder().decodeBuffer(str);
InputStream targetStream = new ByteArrayInputStream(decodedBytes);
PDDocument document = PDDocument.load(targetStream);
document.save("C:/test.pdf");
FileUtils.writeByteArrayToFile(new File("C:/test.pdf"), decodedBytes);
Using above code to convert to pdf.
Getting blob data of pdf from API :
Future<dynamic> getBlobdata(int pdfId) async {
try {
var response = await Dio().get(
"https://www.google.com/pdf/$pdfId",
options: Options(
responseType: ResponseType.bytes,
contentType: 'application/octet-stream',
),
);
var data = {"data": response.data.buffer};
return data;
} on DioError catch (error) {
var data = error.response.data;
return data;
}
}
Define file name and directory to save file :
String fileName = "pdf$pdfId";
final dir = await getExternalStorageDirectory();
var pdfBlob = await getBlobdata(1); // have to be in a asyn func to use await
Save Pdf :
final file = File("${dir.path}/$fileName.pdf");
await file.writeAsBytes(pdfBlob.asUint8List());
View Pdf in app :
await OpenFile.open("${dir.path}/$fileName.pdf");
I want to show the BootStrap's progress bar while am downloading file from Sevlet API.
Application architecture designed like - From React JS using SuperAgent am invoking Servlet API which is responsible for writing a Excel file and it will return that Excel file to the SuperAgent to download the same.
While doing this process i want to show the BootStrap's progress bar for UX.
Please find my code below
Servlet API code for writting a Excel file and return the same to SuperAgent
try {
String reportname = "Invoice";
resp.setContentType("application/vnd.ms-excel");
resp.setHeader("Content-Disposition", "attachment; filename=" +
reportname + ".xls");
HSSFWorkbook workbook1=service.getCommercialInvoiceService(id);
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
workbook1.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
int fileSize=outArray.length;
outStream = resp.getOutputStream();
outStream.write(outArray);
outStream.flush();
outStream.close();
resp.setHeader("Content-Length", ""+fileSize);
} catch (IOException ioe) {
throw new ServletException(ioe);
}
ReactJS method which is using SuperAgent to download file from Servlet API
handleInvoice(e) {
e.preventDefault()
var item = this.state.item;
var lines = item.order;
var request = require('superagent');
var apiBaseUrl = "api/Invoice";
var req = request.get(apiBaseUrl);
req.query({ item : item.id})
req.end(function(err,res) {
if(err) {
alert(" error"+err);
confirmAlert({
message: 'Invoice is not prepared properly.....',
confirmLabel: 'Ok',
});
}
else {
window.location= 'api/Invoice?item=' + item.id,'';
element.click();
}
});
}
I want to show the below bootstrap's progress bar while downloading the file.
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="" aria-
valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
How do i integrate progress bar in ReactJS code ( SuperAgent is invoking the Java Servlet API).
Your code which writes the headers and data is as follows..
int fileSize=outArray.length;
outStream = resp.getOutputStream();
outStream.write(outArray);
outStream.flush();
outStream.close();
resp.setHeader("Content-Length", ""+fileSize);
Note that the content length is being set after the output stream has been written to. HTTP responses consist of a series of headers followed the content, which you write to via the OutputStream. Here you have simply set the content length after streaming the content. So this value is not sent at the start of the response.
The content length of the output is not mandatory (it might not be known by the process streaming it). But of course you can't produce a progress bar unless you know the length of the data. Simply set the content length before writing the data so it makes it into the response headers.
int fileSize=outArray.length;
resp.setHeader("Content-Length", ""+fileSize);
outStream = resp.getOutputStream();
outStream.write(outArray);
outStream.flush();
outStream.close();
I am creating a web application using the Spark Java framework. The front-end is developed using AngularJS.
I want to generate a .docx file on the server (in-memory) and send this to the client for download.
To achieve this I created an angular service with the following function being called after the user clicks on a download button:
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey).success(function (response) {
var element = angular.element('<a/>');
element.attr({
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response,
target: '_blank',
download: 'test.docx'
})[0].click();
});
};
On the server, this api call gets forwarded to the following method:
public Response exportToWord(Response response) {
try {
File file = new File("src/main/resources/template.docx");
FileInputStream inputStream = new FileInputStream(file);
byte byteStream[] = new byte[(int)file.length()];
inputStream.read(byteStream);
response.raw().setContentType("data:attachment;chatset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.raw().setContentLength((int) file.length());
response.raw().getOutputStream().write(byteStream);
response.raw().getOutputStream().flush();
response.raw().getOutputStream().close();
return response;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have tried to solve this in MANY different ways and I always end up with a corrupted 'test.docx' that looks like this:
Solved it by using blobs and specifying the response type as 'arraybuffer' in the $http.post api call. The only bad thing with this solution (as far as I know) is that it doesn't play well with IE, but that's a problem for another day.
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey, {responseType: 'arraybuffer'})
.success(function (response) {
var blob = new Blob([response], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var element = angular.element('<a/>');
element.attr({
href: url,
target: '_blank',
download: 'survey.docx'
})[0].click();
});
};
I think what went wrong was that the byte stream got encoded as plain text when I tried to create a URL with:
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response
thus corrupting it.
When using blobs instead, I get a "direct" link to the generated byte stream and no encoding is done on it since the response type is set to 'arraybuffer'.
Note that this is just my own reasoning of why things went wrong with the original code. I might be terribly wrong, so feel free to correct me if that's the case.
I have C# batch which communicate with salesforce objects via SOAP API.
I want to fetch an image which is part of the Rich Text Field in salesforce custom object.
The rich text field himself is Html text and I can get the url of the image tag, but the problem is that the url himself is Https = Http secure connection:
The url of the image tag:
https://ngam--kerensen--c.cs17.content.force.com/servlet/rtaImage?eid=a1Vg0000000lTkK&feoid=00N20000003jcie&refid=0EMg00000009N4I
As a result of this, I can't get the resource and write it to a file as a local image for later use.
This is the C# code for fetching the image:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
bool answer = response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase);
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect)&&
response.ContentType.StartsWith("text/html", StringComparison.OrdinalIgnoreCase)){
// if the remote file was found, download it
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(filepath))
{
byte[] buffer = new byte[8192];
int bytesRead;
logger.InfoFormat("Writing to file, filepath:{0}", filepath);
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
logger.InfoFormat("bytesRead: {0} ", bytesRead);
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
//TODO outputStream.Close();
}
return true;
}
}
catch (Exception ex)
{
logger.ErrorFormat("Failed to download {0} to {1} : {2}",
uri, filepath, ex.Message);
logger.Debug("Failed to download " + uri, ex);
}
return false;
I know that the secure url using java servlet for exposing the image to the world.
The problem is that I can't get the image data and always get the following respond:
<script>
if (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://ngam--kerensen.cs17.my.salesforce.com?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fngam--kerensen--c.cs17.content.force.com%252Fservlet%252FrtaImage%253Feid%253Da1Vg0000000lTkK%2526feoid%253D00N20000003jcie%2526refid%253D0EMg00000009N4I'); } else
if (window.location.replace){
window.location.replace('https://ngam--kerensen.cs17.my.salesforce.com?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fngam--kerensen--c.cs17.content.force.com%252Fservlet%252FrtaImage%253Feid%253Da1Vg0000000lTkK%2526feoid%253D00N20000003jcie%2526refid%253D0EMg00000009N4I');
} else {;
window.location.href ='https://ngam--kerensen.cs17.my.salesforce.com?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fngam--kerensen--c.cs17.content.force.com%252Fservlet%252FrtaImage%253Feid%253Da1Vg0000000lTkK%2526feoid%253D00N20000003jcie%2526refid%253D0EMg00000009N4I';
}
</script>
Any suggestion how to get the actual image data from the Rich Text Area field.
I have a jsp that makes an AJAX call to a helper jsp which calls a java bean that creates an image. The helper JSP then loads the image into a byte array encodes it to Base64 using Apache commons and returns the string.
File imageFile = new File("test.png");
response.setHeader("Content-Type", getServletContext().getMimeType(imageFile.getAbsolutePath()));
response.setHeader("Content-Length", String.valueOf(imageFile.length()));
FileInputStream is = new FileInputStream(imageFile);
byte[] buffer = new byte[(int)imageFile.length()]; // 32k buffer
int offset = 0;
while ( offset < buffer.length ) {
int count = is.read(buffer, offset, buffer.length - offset);
offset += count;
}
byte[] encoded = Base64.encodeBase64(buffer);
String encodedFile = Base64.encodeBase64String(encoded);
out.print(encodedFile);
out.flush();
Here is the javascript that makes and receives the request for the image:
function getContourImage(startDate, stopDate){
$.ajax("services/contour.jsp", {
data: {
startDate: startDate,
stopDate: stopDate
},
dataType: "json",
traditional: true,
success: contourImageHandler()
});
}
function contourImageHandler(resp){
alert("resp: " + resp);
$( "#plot" ).attr("src","data:image/png;base64," + resp);
}
This is the image display area in the html:
<div id="imageDisplay" name="imageDisplayDiv"
img name="contourImageLocation"
id="plot" src="images/test.png" width="1200" height="1200">
I can see the response in the firebug panel and it seems to have data. The alert statement in the ajax response handler says the response is undefined and no image is placed in the plot location. Does anyone know what I have done wrong?
For the 'displaying the image' part of your problem you can go through this:
http://danielmclaren.com/node/90
Also, it would be better if 'helper jsp' work is moved to a Servlet as you may get additional/junk spaces and line breaks in a jsp response.