This is a common scenario in most of
today web apps.
Today's web applications heavily rely
on json for client server communication. Because json is a totally
text based standard it goes very well until we need to send anything
which is not text, like pdf files and images. And it is not a good
idea that you implement a separate module to transfer binary files,
it will defeat the whole purpose of using json.
I my self struggled a lot to find a
good solution for this. And I didn't found a strait forward and
simple tutorial to handle binary files with json.
So I decided to write one. Please
share your comments and suggestions so I can Improve it.
Theory:
As json only supports text so we have
to convert binary file (pdf, image etc) in to a string. And then we
can easily add it to a json field.
Code Example: In my example I am
using java for server end but you can use your own tools and
languages, Theory will remain same.
I am assuming that you are familiar
with jsp-servlet development thats why I am leaving out unnecessary
implementation details of J2EE application.
Required jar Files :
commons-codec-1.5.jar
Server
End:
//Servlet
public class GetPdfServlet extends
HttpServlet
{
public void doPost(HttpServletRequest
request,HttpServletResponse response )
{
doGet(request,response);
}
public void doGet(HttpServletRequest
request,HttpServletResponse response )
{
PrintWriter pw = null;
try{
pw = response.getWriter();
ByteArrayOutputStream ba=
loadPdf(“myFile.pdf”);
//Converting byte[] to base64 string
//NOTE: Always remember to encode your
base 64 string in utf8 format other wise you may always get problems
on browser.
String pdfBase64String =
org.apache.commons.codec.binary.StringUtils.newStringUtf8(org.apache.commons.codec.binary.Base64.encodeBase64(ba.toByteArray()));
//wrting json response to browser
pw.println("{");
pw.println("\"successful\":
true,");
pw.println("\"pdf\":
\""+pdfBase64String+"\"");
pw.println("}");
return;
}catch(Exception ex)
{
pw.println("{");
pw.println("\"successful\":
false,");
pw.println("\"message\":
\""+ex.getMessage()+"\",");
pw.println("}");
return;
}
}
private ByteArrayOutputStream
loadPdf(String fileName)
{
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[]
buf = new byte[1024];
try {
for
(int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum); //no doubt here is 0
}
} catch
(IOException ex) {
ex.printStackTrace();
}
return bos;
}
}
Client
End :
index.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Example</title>
<script
type="text/javascript" src="/js/loadPdf.js"></script>
</head>
<body>
<div id='dataFormContainer'>
</div>
<form>
<input type='button'
value='getPDF' onClick='getPdf()'>
</form>
</body>
</html>
LoadPdf.js
function getPdf()
{
var ax = getXMLHttpRequest();
ax.open('POST', "[your servlet
url]",true);
ax.onreadystatechange=function()
{
if(ax.readyState==4 &&
ax.status==200)
{
var dataFormContainer =
document.getElementById("dataFormContainer");
var response =
eval("("+ax.responseText+")");
if(response.successful)
{
var url =
"data:application/pdf;base64,"+response.pdf;
var _iFrame =
document.createElement('iframe');
_iFrame.setAttribute('src', url);
dataFormContainer.appendChild(_iFrame);
}
}
}
ax.send();
}
NOTE: Always remember to encode your
base 64 string in utf8 format at server end other wise you may always
get problems on browser.