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.
Related
How to receive an image file through Rest APIs. There is an option of MULTIPART_FORM_DATA which looks like it will send files in parts as in more than one request.
I want to receive images very fast on server. around 2 images per second.
Simply read image in a File and use Response class to build the response.
Response.ok(new File("myimage.jpg"), "image/jpeg").build();
There are other variations of the same.
Read the image using following.
URL url = new URL("http://localhost:8080/myimage/1");
URLConnection connection = url.openConnection();
input = connection.getInputStream();
byte[] buffer = new byte[1024];
int n = - 1;
OutputStream fos = new FileOutputStream("Output.jpg" );
while ( (n = input.read(buffer)) != -1)
{
fos.write(buffer, 0, n);
}
fos.close();
You can use Apache HTTP client to make it prettier.
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.
I have a simple JSP page, which contains 2 buttons: View and Export. When View button is clicked I will fetch data from DB, keep a copy into session and write an HTML code into a label with the data. Later when user clicks Export I want to generate an excel file in the server(with the data from session) and download it to clientside.
Excel file is successfully created at serverside. I am using an AJAX request from clientside to download Excel file from server.
JSP code:
try{
String filepath=ExportToExcel(session.getAttribute("InvestmentDetails"));
//Setting file to download
response.setContentType( "application/x-download");
response.setHeader("Content-Disposition","attachment; filename=\"SIPInvestment_531.xls\"");
response.setStatus(200);
InputStream in = null;
ServletOutputStream outs = response.getOutputStream();
try {
File filetodownload=new File(filepath);
response.setContentLength(Integer.parseInt(String.valueOf(filetodownload.length())));
in = new BufferedInputStream(new FileInputStream(filetodownload));
int ch;
while ((ch = in.read()) != -1) {
outs.print((char) ch);
}
}
finally {
if (in != null) in.close();
}
outs.flush();
outs.close();
}
catch(Exception ex){
str=ex.getMessage();
}
Here is the Javascript:
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
}
}
xmlhttp.open("POST","/SIP/rptClientInvestmentDetails.jsp?requesttype=export",false);
xmlhttp.send();
The request reaches on JSP page. And without any exception it writes to response outputstream. But no download is pop up from browser. What can be the problem?
Ajax should be used for meta-languages, not for binary files.
A simple
<a href="/SIP/rptClientInvestmentDetails.jsp?requesttype=export"
target="_blank">Export</a>
is all you need.
If you make sure you said the response.setHeader("Content-Disposition","attachment you should drop the target-attribute as BalusC suggested.
I think you can use location.href="Provide the java class function name".This will transfer the control from jsp to java function without using the ajax call
I need to create a file upload handler as a REST web service with CXF. I've been able to upload a single file with metadata using code like the following:
#POST
#Path("/uploadImages")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadImage(#Multipart("firstName") String firstName,
#Multipart("lastName") String lastName,
List<Attachment> attachments) {
for (Attachment att : attachments) {
if (att.getContentType().getType().equals("image")) {
InputStream is = att.getDataHandler().getInputStream();
// read and store image file
}
}
return Response.ok().build();
}
Now I need to add support for uploading multiple files in the same request. In this case, instead of an attachment with image/jpeg content type, I get an attachment with multipart/mixed content type, which itself contains the individual image/jpeg attachments that I need.
I've seen examples for uploading multiple JSON or JAXB objects with metadata, but I have not been able to get anything to work with binary image data. I have tried using the MultipartBody directly, but it only returns the multipart/mixed attachment, not the image/jpeg attachments embedded within it.
Is there a way to recursively parse a multipart/mixed attachment to get the embedded attachments? I can of course get the input stream of the multipart/mixed attachment, and parse out the files myself, but I'm hoping there is a better way.
UPDATE
This seems kludgey, but the following bit of code is good enough for now. I would love to see a better way though.
for (Attachment att : attachments) {
LOG.debug("attachment content type: {}", att.getContentType().toString());
if (att.getContentType().getType().equals("multipart")) {
String ct = att.getContentType().toString();
Message msg = new MessageImpl();
msg.put(Message.CONTENT_TYPE, ct);
msg.setContent(InputStream.class, att.getDataHandler().getInputStream());
AttachmentDeserializer ad = new AttachmentDeserializer(msg, Arrays.asList(ct));
ad.initializeAttachments();
// store the first embedded attachment
storeFile(msg.getContent(InputStream.class));
// store remaining embedded attachments
for (org.apache.cxf.message.Attachment child : msg.getAttachments()) {
storeFile(child.getDataHandler().getInputStream());
}
}
else if (att.getContentType().getType().equals("image")) {
storeFile(att.getDataHandler().getInputStream());
}
}
I've build a similar service to upload multiple images. My implementation looks like the following (maybe it helps)
#Consumes({MediaType.MULTIPART_FORM_DATA,"multipart/mixed" })
public Response uploadImages(final List<Attachment> attachments) {
Map<String, InputStream> imageMap = new HashMap<String, InputStream>();
for (Attachment attachment : attachments) {
String imageName = attachment.getContentDisposition().getParameter("filename");
if (imageName == null) {
imageName = UUID.randomUUID().toString();
}
InputStream image = attachment.getDataHandler().getInputStream();
imageMap.put(imageName, image);
}
return imageMap;
}
if someone prefers bye arrays instead of input streams, it can be converted easily using this helper method
private static byte[] extractByteArray(final InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] dataChunk = new byte[1024 * 16];
int numRead = 0;
while (numRead != -1) {
numRead = inputStream.read(dataChunk, 0, dataChunk.length);
if (numRead != -1) {
buffer.write(dataChunk, 0, numRead);
}
}
buffer.flush();
return buffer.toByteArray();
}
I'm running a site where users can link images and thumbnails from other sites in their content. When viewing these images in the https secured user are, they are getting security warnings, because http content is contained in the https page..
To work around this, I'd like to route the images through my server to the client, there by "giving" them the required https protokoll.
e.g. when viewing content on the secure site an image tag would like this:
<img src="https://mysite/img.aspx?src=http://url.to/someimage.jpg" >
As my site using Umbraco (.NET 3.5, IIS7), I've already looked into using the urlrewritingnet library, but it only seems to be able to rewrite and redirect urls.
Has anybody done this?
The following works quite well:
I've got it to work by just passsing through the image bytes on the server. I'm not entierly convinced that it is a good solution so, I'll wait for better solutions:
public partial class Img : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string url = Page.Request.QueryString["url"];
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Timeout = 5000;
request.ReadWriteTimeout = 20000;
HttpWebResponse imgresponse = (HttpWebResponse)request.GetResponse();
//StreamReader sr = new StreamReader(imgresponse.GetResponseStream());
Response.ContentType = "image/gif";
byte[] fileBytes = GetFileBytes(imgresponse.GetResponseStream());
Response.BinaryWrite(fileBytes);
Response.Flush();
}
protected byte[] GetFileBytes(Stream stream)
{
byte[] fileBytes = null;
byte[] buffer = new byte[4096];
try
{
MemoryStream memoryStream = new MemoryStream();
int chunkSize = 0;
do
{
chunkSize = stream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, chunkSize);
} while (chunkSize != 0);
fileBytes = memoryStream.ToArray();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
return fileBytes;
}
}