Attachment API - excel getting uploaded but corrupted while downloading
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-10-2019 09:46 PM
I am invoking the https://<host>/api/now/attachment/upload service using HTTPUrlConnection
the uploaded file is being read via HTML file upload <input type="file" name="file" id="file" multiple="true">
And AJAX call is used to invoke the servlet where I am sending request to upload service. The problem is I can see the attachment uploaded in ticket but I suspect as encoding is not correct, its not getting downloaded, Please help
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @param charset
* @throws IOException
*/
public MultipartUtility(String requestURL, String charset,String encoding)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_IP, PROXY_PORT));
System.out.println("URL : " + requestURL);
httpConn = (HttpURLConnection) url.openConnection(proxy);
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
httpConn.setRequestProperty("Authorization","Basic " + encoding);
httpConn.setRequestProperty("Accept","application/json");
httpConn.setRequestMethod("POST");
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
* Adds a form field to the request
*
* @param name field name
* @param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
* Adds a upload file section to the request
*
* @param fieldName name attribute in <input type="file" name="..." />
* @param uploadFile a File to be uploaded
* @param fileContent File inputStream
* @throws IOException
*/
public void addFilePart(String fieldName, String fileName, InputStream fileContent)
throws IOException {
// String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
// writer.append(
// "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
writer.append("Content-Type: application/octet-stream")
// + URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
// try (FileInputStream inputStream = (FileInputStream)fileContent;) {
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = fileContent.read(buffer)) != -1) {
System.out.println("bytes to read");
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
// }
writer.append(LINE_FEED);
writer.flush();
}
* Adds a header field to the request.
*
* @param name - name of the header field
* @param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}
* Completes the request and receives response from the server.
*
* @return a list of Strings as response in case the server returned
* status OK, otherwise an exception is thrown.
* @throws IOException
*/
public String finish() throws IOException {
StringBuffer response = new StringBuffer();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_CREATED) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
}
}
String fileName = null;
InputStream fileContent = null;
ServletContext sc = request.getSession().getServletContext();
String uploadPath = sc.getRealPath("") + File.separator + TMP_DIRECTORY;
if (ServletFileUpload.isMultipartContent(request)) {
List<Part> fileParts = request.getParts().stream().filter(part -> "file".equals(part.getName())).collect(Collectors.toList()); // Retrieves <input type="file" name="file" multiple="true">
fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
fileContent = filePart.getInputStream();
System.out.println("File Name in Attachment upload:" + fileName);
}
String encoding = Base64.getEncoder().encodeToString(authString.getBytes());
String charset = "UTF-8";
multipart.addHeaderField("Content-Type", "multipart/form-data");
multipart.addHeaderField("Accept", "application/json");
// multipart.addHeaderField("Authorization", "Basic" + encoding);
multipart.addFormField("table_name", "change_request");
multipart.addFormField("table_sys_id", sysId);
multipart.addFilePart("uploadFile", fileName, fileContent);
String respons = multipart.finish();
System.out.println("Attachment Upload Response:"+respons);
I am clueless as to where I am going wrong. On downloading file, am unable to view in excel, it says either file format not correct or corrupted.
Thanks,
Heena
- Labels:
-
Team Development
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-12-2019 01:42 AM
Hi Heena,
So basically from Java code you want to upload attachment?
Mark ✅ Correct if this solves your issue and also mark 👍 Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-12-2019 02:29 AM
Hi Ankur,
I resolved the issue myself, while I was able to upload csv and txt file, excel file (.xlsx) upload wasn't working. As per my understanding, the content-type and content-transfer-encoding was not going as required.
modified addFilePart method as follows
public void addFilePart(String fieldName, String fileName, InputStream fileContent)
throws IOException {
// String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
guessContentTypeFromFile(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
byte[] content = IOUtils.toByteArray(fileContent);
outputStream.write(content);
outputStream.flush();
fileContent.close();
writer.flush();
}
public String guessContentTypeFromFile(String fileName) {
String contentType = URLConnection.guessContentTypeFromName(fileName);
if (contentType == null) {
return "application/octet-stream";
} else {
return contentType;
}
}
I can now upload an excel sheet with this code. However, the response received still shows content-type as "text/plain".
Thanks,
Heena
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-12-2019 04:28 AM
Hi Heena,
Thanks for sharing the update
Regards
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader