Downloading Docusign PDF in Grails, file corrupted - grails

Using Groovy 1.8.6 and Grails 2.1.0
Using embedded API, after user signs document, browser is redirected back to my app. Using "Get Envelope Documents and Certificate" API to download document to server. URL format:
"${baseUrl}/envelopes/${envelopeId}/documents/combined"
Code snippet (with minor details removed):
private void getDocument(requestUrl) {
def connection = urlConnect(requestUrl, null, "GET")
if (connection.responseCode == 200) {
savePDF(envelopeId, connection.inputStream)
}
}
private void savePDF(envelopeId, inputStream) {
String filePath = getSavedPDFPath(envelopeId)
def pdfWriter = new File(filePath).newWriter()
pdfWriter << inputStream
pdfWriter.close()
}
What happens is that the resulting file is not 100% correct, Adobe Reader complains that "at least one signature is invalid". Reader at least knows that the file was signed by DocuSign, Inc., and can show details about the certificate.

Per the Question's comment thread, the issue was being caused by the way the file was being saved. Using this code instead, the file saves / opens correctly:
private void savePDF(envelopeId, connection)
{
FileOutputStream fop = null;
File file;
String filePath = getSavedPDFPath(envelopeId);
try {
file = new File(filePath);
fop = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int numRead;
while((numRead = connection.getInputStream().read(buffer)) > 0)
{
fop.write(buffer, 0, numRead);
}
fop.flush();
fop.close();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}

Related

The problem of FormDataContentDisposition in Jersey File Upload

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/files")
public class FileUploadService {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces({"text/plain","application/xml","application/json"})
public Response uploadPdfFile( #FormDataParam("file") InputStream fileInputStream,
#FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception
{
//String UPLOAD_PATH = "f://";
String UPLOAD_PATH = "c://temp//";
try
{
int read = 0;
byte[] bytes = new byte[102400];
OutputStream out = new FileOutputStream(new File(UPLOAD_PATH +
fileMetaData.getFileName()));
//OutputStream out = new FileOutputStream(new File(UPLOAD_PATH + "xx.txt"));
while ((read = fileInputStream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e)
{
throw new WebApplicationException("Error while uploading file. Please try again !!");
}
return Response.ok("Data uploaded successfully !!").build();
}
}
A code of Jersey upload was running. If I use OutputStream out = new FileOutputStream(new File(UPLOAD_PATH + "xx.txt")), it is good and I can see the xx.txt file in c:\temp folder.
However, if I use OutputStream out = new FileOutputStream(new File(UPLOAD_PATH + fileMetaData.getFileName())), it said Data uploaded successfuly!!, but I cannot see anything in c:\temp folder.
Did this FormDataContentDisposition have any bug? Or I use it in wrong way?
The line "return Response.ok("Data uploaded successfully !!").build();" will return "Data uploaded successfully !!".
However, if I change the line "return Response.ok("Data uploaded successfully !!").build(); to return Response.ok("Data uploaded successfully !!"+fileMetaData.getFileName()).build();
I got the results of "Data uploaded successfully !!C:CodingWeb services16.JAX-RS File Upload Exampletest.txt".
Why did fileMetaData.getFileName() return "C:CodingWeb services16.JAX-RS File Upload Exampletest.txt"?

JavaMail MIME attachment link by cid

Background
I have banged my head against this for a while and not made much progress. I am generating MPEG_4 / AAC files in Android and sending them by email as .mp3 files. I know they aren't actually .mp3 files, but that allows Hotmail and Gmail to play them in Preview. They don't work on iPhone though, unless they are sent as .m4a files instead which breaks the Outlook / Gmail Preview.
So I have thought of a different approach which is to attach as a .mp3 file but have an HTML link in the email body which allows the attached file to be downloaded and specifies a .m4a file name. Gmail / Outlook users can click the attachment directly whereas iPhone users can use the HTML link.
Issue
I can send an email using JavaMail with HTML in it including a link which should be pointing at the attached file to allow download of that file by the link. Clicking on the link in Gmail (Chrome on PC) gives a 404 page and iPhone just ignores my clicking on the link.
Below is the code in which I generate a multipart message and assign a CID to the attachment which I then try to access using the link in the html part. It feels like I am close, but maybe that is an illusion. I'd be massively grateful if someone could help me fix it or save me the pain if it isn't possible.
private int send_email_temp(){
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", smtp_host_setting);
//props.put("mail.debug", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.port", smtp_port_setting);
session = Session.getInstance(props);
ActuallySendAsync_temp asy = new ActuallySendAsync_temp(true);
asy.execute();
return 0;
}
class ActuallySendAsync_temp extends AsyncTask<String, String, Void> {
public ActuallySendAsync_temp(boolean boo) {
// something to do before sending email
}
#Override
protected Void doInBackground(String... params) {
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(recipient_email_address));
message.setSubject(email_subject);
Multipart multipart = new MimeMultipart();
MimeBodyPart messageBodyPart = new MimeBodyPart();
String file = mFileName;
/**/
DataSource source = new FileDataSource(file);
messageBodyPart.setDataHandler(new DataHandler(source));
/* /
File ff = new File(file);
try {
messageBodyPart.attachFile(ff);
} catch(IOException eio) {
Log.e("Message Error", "Old Macdonald");
}
/* /
messageBodyPart = new PreencodedMimeBodyPart("base64");
byte[] file_bytes = null;
File ff = new File(file);
try {
int length = (int) ff.length();
BufferedInputStream reader = new BufferedInputStream(new FileInputStream(ff));
file_bytes = new byte[length];
reader.read(file_bytes, 0, length);
reader.close();
} catch (IOException eio) {
Log.e("Message Error", "Old Macdonald");
}
messageBodyPart.setText(Base64.encodeToString(file_bytes, Base64.DEFAULT));
messageBodyPart.setHeader("Content-Transfer-Encoding", "base64");
/**/
messageBodyPart.setFileName( DEFAULT_AUDIO_FILENAME );//"AudioClip.mp3");
//messageBodyPart.setContentID("<audio_clip>");
String content_id = UUID.randomUUID().toString();
messageBodyPart.setContentID("<" + content_id + ">");
messageBodyPart.setDisposition(Part.ATTACHMENT);//INLINE);
messageBodyPart.setHeader("Content-Type", "audio/mp4");
multipart.addBodyPart(messageBodyPart);
MimeBodyPart messageBodyText = new MimeBodyPart();
//final String MY_HTML_MESSAGE = "<h1>My HTML</h1><a download=\"AudioClip.m4a\" href=\"cid:audio_clip\">iPhone Download</a>";
final String MY_HTML_MESSAGE = "<h1>My HTML</h1><a download=\"AudioClip.m4a\" href=\"cid:" + content_id + "\">iPhone Download</a>";
messageBodyText.setContent( MY_HTML_MESSAGE, "text/html");
multipart.addBodyPart(messageBodyText);
message.setContent(multipart);
Print_Message_To_Console(message);
Transport transport = session.getTransport("smtp");
transport.connect(smtp_host_setting, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
} catch (MessagingException e) {
e.printStackTrace();
} finally {
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// something to do after sending email
}
}
int Print_Message_To_Console(Message msg) {
int ret_val = 0;
int line_num = 0;
InputStream in = null;
InputStreamReader inputStreamReader = null;
BufferedReader buff_reader = null;
try {
in = msg.getInputStream();
inputStreamReader = new InputStreamReader(in);
buff_reader = new BufferedReader(inputStreamReader);
String temp = "";
while ((temp = buff_reader.readLine()) != null) {
Log.d("Message Line " + Integer.toString(line_num++), temp);
}
} catch(Exception e) {
Log.d("Message Lines", "------------ OOPS! ------------");
ret_val = 1;
} finally {
try {
if (buff_reader != null) buff_reader.close();
if (inputStreamReader != null) inputStreamReader.close();
if (in != null) in.close();
} catch(Exception e2) {
Log.d("Message Lines", "----------- OOPS! 2 -----------");
ret_val = 2;
}
}
return ret_val;
}
You need to create a multipart/related and set the main text part as the first body part.

sending json data to server in blackberry

In my application i have to integrate API. I am not getting code for how to check whether internet is available or not. How to send JSON Data to server. Please help me out. As in android we call API in AsyncTask class. In blackberry i did not found like this.
Suggest me some link or ideas so that i can integrate code. I am googling. But did not getting result .
What I have tried is here:
JSONObject postData = new JSONObject();
postData.put("userId", "24");
postData.put("messageTime","06:00:00");
postData.put("language", language[lang_Ocf.getSelectedIndex()]);
System.out.println("********json********"+postData);
ConnectionFactory conFactory = new ConnectionFactory();
ConnectionDescriptor conDesc = null;
try
{
conDesc = conFactory.getConnection(url+";deviceside=true");
}
catch(Exception e)
{
System.out.println(e.toString()+":"+e.getMessage());
}
String response = ""; // this variable used for the server response
// if we can get the connection descriptor from ConnectionFactory
if(null != conDesc)
{
try
{
HttpConnection connection = (HttpConnection)conDesc.getConnection();
//set the header property
connection.setRequestMethod(HttpConnection.POST);
connection.setRequestProperty("Content-Length", Integer.toString(postData.length()));
connection.setRequestProperty("Content-Type","application/json");
OutputStream out = connection.openOutputStream();
out.write(postData.get);
out.flush();
out.close();
int responseCode = connection.getResponseCode();
if(responseCode == HttpConnection.HTTP_OK){
InputStream in = connection.openInputStream();
StringBuffer buf = new StringBuffer();
int read = -1;
while((read = in.read())!= -1)
buf.append((char)read);
response = buf.toString();
}
Dialog.inform(response);
connection.close();
} catch(Exception e) {
}
}
return response;
Thanks
I solved this problem
Error:
Error: Cannot run program "jar": CreateProcess error=2, The system cannot find the file specified Packaging project HelaBibleWhereUR failed (took 10.715 seconds)
I simply put jar.exe that is under java bin folder in the jre bin folder.

Mobile web application: download attachments on iOS

In my mobile web application i have one page within user can view attachments.
The attachment can be any type of file (jpg,png,txt,doc,zip, etc).
The view attachment action is in the form of <a> tag that points to an aspx file that process the request.
HTML:
<a class="attachBtn" href="_layouts/ViewFile.aspx?messageAttachmentInstanceId={some id}"></a>
ViewFile.aspx:
public partial class ViewFile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.IO.BinaryWriter bw = null;
System.IO.MemoryStream ms = null;
System.IO.StreamReader sr = null;
try
{
string contentType = string.Empty;
byte[] content = null;
string fileName = string.Empty;
if (!string.IsNullOrEmpty(Request.QueryString["messageAttachmentInstanceId"]) &&
!string.IsNullOrEmpty(Request.QueryString["messageInstanceId"]))
{
int messageInstanceId = Int32.Parse(Request.QueryString["messageInstanceId"]);
Guid attachmentInstanceId;
GuidUtil.TryParse(Request.QueryString["messageAttachmentInstanceId"], out attachmentInstanceId);
MessageInstance messageInstance = WorkflowEngineHttpModule.Engine.GetService<IMessagingService>()
.GetMessageInstance(messageInstanceId);
if (messageInstance != null)
{
MessageAttachmentInstance attachmentInstnace = messageInstance.Attachments[attachmentInstanceId];
contentType = attachmentInstnace.ContentType;
fileName = attachmentInstnace.FileName;
content = attachmentInstnace.Content;
}
}
this.Response.ContentType = contentType;
string headerValue = string.Format("attachment;filename={0}",
this.Server.UrlPathEncode(fileName));
Response.AddHeader("content-disposition", headerValue);
bw = new System.IO.BinaryWriter(this.Response.OutputStream);
bw.Write(content);
}
catch (Exception ex)
{
LogError("ViewFile.aspx, "
+ ex.InnerException, ex);
}
finally
{
if (sr != null)
sr.Close();
if (ms != null)
ms.Close();
if (bw != null)
bw.Close();
}
}
}
The Problem:
in Android devices when user click on attachment the file is downloaded automatically which is the desirable behavior because the user can open the file later with any tool he wants and even if the file type is not supported user can later on download a tool which can open it.
but in iOS devices the file is not downloaded but instead redirects to ViewFile.aspx and tries to open the file within the browser and if the file type is not supported it shows alert: "safari cannot download this file".
even if the file type is supported i want it to be downloaded and not open by default.
How can i achieve this behavior?
AFAIK, you cannot download files on iOS.
Known files that Safari (or any app that has registered a file type, e.g. ZIP) supports will open or show a dialog letting the user choose how to open the file.
You can't control the behavior from your web app/site.

Accessing the 'Media' directory of a Blackberry within the JDK

Trying to use JSR 75 to access media saved under the '/home/video/' directory on the device. Using Blackbery JDK 4.6.1. Single line of code throws a 'FileSystem IO Error' Exception. Which is, as usual, unhelpful in the extreme.
fconn = (FileConnection)Connector.open("file:///home/user/videos/"+name, Connector.READ);
Has anyone tried to do this? I can open files within my jar, but can't seem to access the media folder. I have the javax.microedition.io.Connector.file.read permission set and my appplication is signed.
There are two kind of filesystems on BlackBerry - SDCard and store. You have to use one of them, defining it in the path. Standard directory on SDCard where video, music etc stored is "file:///SDCard/BlackBerry".
String standardPath = "file:///SDCard/BlackBerry";
String videoDir = System.getProperty("fileconn.dir.videos.name");
String fileName = "video.txt";
String path = standardPath+"/"+videoDir+"/"+fileName;
String content = "";
FileConnection fconn = null;
DataInputStream is = null;
ByteVector bytes = new ByteVector();
try {
fconn = (FileConnection) Connector.open(path, Connector.READ);
is = fconn.openDataInputStream();
int c = is.read();
while(-1 != c)
{
bytes.addElement((byte) (c));
c = is.read();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
content = new String(bytes.toArray());
add(new RichTextField(content));
See also
SUN Dev Network - Getting Started with the FileConnection APIs
RIM Forum - Some questions about FileConnection/JSR 75
Use System.getProperty("fileconn.dir.memorycard") to check if SDCard available
How to save & delete a Bitmap image in Blackberry Storm?

Resources