- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-18-2014 09:21 PM
So I have been working on an integration and was curious if anyone has successfully created a multipart/form-data outbound REST request with binary image data in Servicenow? With or without use of mid server. I know the request works because it works fine in Fiddler and Restify. Below is the body I am using, I have been able to post this exact message with a text file so I know the issue is with the binary I am sending. I have also tried base64. Does anyone have any tips or tricks for sending binary image data with Javascript? Any pitfalls or issues you have ran into in the past? Thanks !
--gc0p4Jq0M2Yt08jU534c0p
Content-Disposition: form-data; name="body"
goes with message
--gc0p4Jq0M2Yt08jU534c0p
Content-Disposition: form-data; name="attachment1"; filename="testpic.gif"
Content-Type:image/gif
Content-Transfer-Encoding: binary
${attachment}
--gc0p4Jq0M2Yt08jU534c0p--
Solved! Go to Solution.
- Labels:
-
Service Mapping
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-21-2014 10:11 PM
Yes, I finally got this done with a custom .jar file and Javascript probe. I wrote a reply on
JavascriptProbe and MID Server Script Includes-John Andersen
I believe you must be the same Jonathan, let me know if you have any questions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-27-2015 09:01 PM
Hi Nick,
We are doing Integration between ServiceNow and JIRA where we need to send attachments to JIRA using REST API.
So, I wrote a Mid Server Script Include which contains the code as below.
var pathname= "/nav_to.do?uri=sys_attachment.do?sys_id=f646a0df4f0a020079b94fe18110c79c";
var fileUpload = new Packages.java.io.File(pathname);
var httpClient = new Packages.org.apache.commons.httpclient.HttpClient();
var postRequest = new Packages.org.apache.commons.httpclient.methods.PostMethod("----------------------------");
postRequest.setHeader("Authorization", "Basic");
postRequest.setHeader("username", "------");
postRequest.setHeader("password", "--------");
postRequest.setHeader("X-Atlassian-Token","nocheck");
var parts = new Packages.org.apache.commons.httpclient.methods.multipart.FilePart(fileUpload.getName(),fileUpload);
var entity=new Packages.org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity(parts,postRequest.getParams());
postRequest.setRequestEntity(entity);
var response = httpClient.execute(postRequest);
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
Issue is:
While I try to execute this using Javascript Probe, Iam getting error at
var parts = new Packages.org.apache.commons.httpclient.methods.multipart.FilePart(fileUpload.getName(),fileUpload);
Error is "java.io.FileNotFoundException: File is not a normal file".
Could you please help me on this in knowing what is the mistake.
Thanks in advance
Sreeja
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-28-2015 10:59 AM
Ok looks a little different than what I did, but I will tell you what I see that is different.
For the first two lines.
var pathname= "/nav_to.do?uri=sys_attachment.do?sys_id=f646a0df4f0a020079b94fe18110c79c";
var fileUpload = new Packages.java.io.File(pathname);
I didn't pass in the files this way, I ended up converting the Base64 string to a byte array and then attaching it to the request. I am no Java expert but I am not sure if the java.io.File object in java takes a base64 string as an argument does it? Because remember files are stored as Base64 in ServiceNow.
I did something like this.
import org.apache.commons.codec.binary.Base64
byte [] decodedBytes = (Base64.decodeBase64(b64string.getBytes()));
String message = "New File attached";
Part[] parts ={
new StringPart("body", message),
new FilePart("atttachment1", new ByteArrayPartSource(filename,decodedBytes), contentType, null)
};
Also another thing that you might need to look at is the boundary and content type. Again I am not an expert in HTTP but I know the boundary header/parameter is required when building multipart requests so you may want to look at that too.
I set it like this.
postRequest.setRequestHeader("Content-Type", "multipart/form-data;boundary=" + boundary);
I honestly didn't have any luck sending a base64 string in a REST request. I would try this if you are not having luck with it either. Let me know if that helps at all.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-06-2016 08:53 AM
Hello Nick,
Can you provide some code/jar from your solution. I'm doing something similar, this would be of great help.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-07-2016 09:16 AM
I was able to accomplish this by using a MID Server Script include and using these functions, see if they help you:
_getURLConnection: function(url) {
if (ms.getConfigParameter("mid.proxy.use_proxy") == 'true') {
Packages.java.lang.System.setProperty("https.proxyHost", ms.getConfigParameter("mid.proxy.host"));
Packages.java.lang.System.setProperty("http.proxyHost", ms.getConfigParameter("mid.proxy.host"));
Packages.java.lang.System.setProperty("https.proxyPort", ms.getConfigParameter("mid.proxy.port"));
Packages.java.lang.System.setProperty("http.proxyPort", ms.getConfigParameter("mid.proxy.port"));
}
var conn = new Packages.java.net.URL(url).openConnection();
this.logMsg("Sending to : " + url, "debug");
var userpass = new Packages.java.lang.String(this.probeParameters.username + ":" + this.probeParameters.password);
conn.setRequestProperty("X-Atlassian-Token", "nocheck");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + this.boundary);
var basicAuth = "Basic " + (new Packages.javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes()) + '');
conn.setRequestProperty("Authorization", basicAuth);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
return conn;
},
_getFile: function() {
//Get The File as Base64 and convert to ByteArrayInputStream
return new Packages.com.glide.util.StringUtil.base64DecodeAsBytes(this.probeParameters.encpayload);
},
_writeFile: function(conn, uploadFile) {
var outputStream = conn.getOutputStream();
var writer = new Packages.java.io.PrintWriter(new Packages.java.io.OutputStreamWriter(outputStream, this.charset), true);
var fieldName = 'file'; // JIRA Requires this as 'file'
var fileName = this.probeParameters.fileName;
this.logMsg("Sending file : " + fileName, "debug");
writer.append("--" + this.boundary).append(this.LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(this.LINE_FEED);
//Sometimes ServiceNow does not have the content type for a file (attempt to get it, otherwise default to octet-stream):
if (JSUtil.notNil(this.probeParameters.contentType)) {
writer.append("Content-Type: " + this.probeParameters.contentType).append(this.LINE_FEED);
} else if (JSUtil.notNil(Packages.java.net.URLConnection.guessContentTypeFromName(fileName))) {
writer.append("Content-Type: " + Packages.java.net.URLConnection.guessContentTypeFromName(fileName)).append(this.LINE_FEED);
} else {
writer.append("Content-Type: application/octet-stream").append(this.LINE_FEED);
}
writer.append("Content-Transfer-Encoding: binary").append(this.LINE_FEED);
writer.append(this.LINE_FEED).flush();
this._writeFileData(uploadFile, outputStream);
writer.append(this.LINE_FEED).flush();
writer.append(this.LINE_FEED).flush();
writer.append("--" + this.boundary + "--").append(this.LINE_FEED);
writer.close();
var readResponse = "";
if (conn.getResponseCode() == 200) {
var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(conn.getInputStream()));
var line = reader.readLine();
while (line != null) {
readResponse += line;
line = reader.readLine();
}
}
return conn.getResponseCode();
},
_writeFileData: function(uploadFile, outputStream) {
var inputStream = new Packages.java.io.ByteArrayInputStream(uploadFile);
var data = new Packages.java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096);
var bytesRead = 0;
while ((bytesRead = inputStream.read(data)) != -1) {
outputStream.write(data, 0, bytesRead);
outputStream.flush();
}
inputStream.close();
},
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-07-2016 09:40 AM
Thanks Jonathan