How to encode xml to Base64 and send back as servlet response? - servlets

I wrote a servlet (with .groovy extension) which should return xml in Base64 encoding
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String fileName=(String) request.getParameter("fileName")
if (fileName == null || fileName.equals(""))throw new ServletException("Invalid or non-existent file parameter in SendXml servlet.")
if (fileName.indexOf(".xml") == -1)fileName = fileName + ".xml"
System.out.println(fileName)
try {
String relativeWebPath = "/WEB-INF/classes/com/abc/csm/xml/"+fileName
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath)
String fileContents=new File(absoluteDiskPath).text
response.setContentType("text/xml")
response.addHeader("Content-Disposition", "attachment filename="+ fileName)
XmlHandler xm=new XmlHandler()
PrintWriter out = response.getWriter()
String enxml=xm.encodeBase64(fileContents)
response.setContentLength((int) enxml.length)
out.println(enxml)
out.close()
out.flush()
} catch (Exception e) { println e }
}
XmlHandler encodeBase64 method
def encodeBase64(String text) {
return new String(Base64.encodeBase64(text.getBytes()))
}
But I guess something is missing. Please help
Update
Also please comment is it proper way to access files from package?

You can replace:
String enxml=xm.encodeBase64(fileContents)
with
String enxml = fileContents.bytes.encodeBase64()
Or, better to pass an encoding to the call to getBytes:
String enxml = fileContents.getBytes( 'UTF-8' ).encodeBase64()
Also, I believe you're missing a semicolon after attachment in your header... The line should read:
response.addHeader( "Content-Disposition", "attachment; filename=$fileName" )
Edit, and encoding and decoding example:
Encode:
String encoded = "tim_yates".getBytes( 'UTF-8' ).encodeBase64()
Decode:
String original = new String( encoded.decodeBase64(), 'UTF-8' )
assert original == 'tim_yates'

Related

HttpServletResponse as an argument

I am pretty new to servlets and I would like to ask a kind of silly question.
I have a method that has an HttpServletResponse argument and I need to call this method from my main method to run the Java program.
The thing is I do not know what should I pass as value for this argument.
Let's say I have this class that comes from CrystalReports:
private static void exportIt(ReportClientDocument clientDoc, ExportOptions exportOptions, HttpServletResponse response, boolean attachment, String mimeType, String extension)
throws ReportSDKExceptionBase, IOException {
InputStream is = null;
try {
is = new BufferedInputStream(clientDoc.getPrintOutputController().export(exportOptions));
byte[] data = new byte[1024];
response.setContentType(mimeType);
if (attachment)
{
String name = clientDoc.getReportSource().getReportTitle();
if (name == null)
{
name = "CrystalReportViewer";
}
else
{
name = name.replaceAll("\"", "");
}
response.setHeader("Content-Disposition",
"attachment; filename=\"" + name + "."+extension+"\"");
}
OutputStream os = response.getOutputStream();
while (is.read(data) > -1) {
os.write(data);
}
} finally {
if (is != null) {
is.close();
}
}
}
When I try to call the exportIt method I need to pass something in the HTTPServletResponse but I do not know what is the exact value.
Thank you for your help,

HTTP POST receiving more than one HTTP Response

I have an http POST being actioned via a .NET System.Net.WebRequest as follows:
...
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has uri={0}, body={1}", uri, messageBodyAsString));
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(messageBodyAsString);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return null;
System.IO.StreamReader sr =
new System.IO.StreamReader(resp.GetResponseStream());
string rs = sr.ReadToEnd().Trim();
sr.Close();
resp.Close();
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has string response = {0}", rs));
MongoDB.Bson.BsonDocument doc2 = new BsonDocument();
doc2.Add("Response", rs);
return doc2;
}
}
catch (System.Net.WebException e)
{...
This all works fine most of the time. However, looking at the log files that this creates I spotted something strange. The suspect log entries look like this:
18:59:17.0608 HPSHTTPPost PostToUri has uri=https://salesforce.ringlead.com/cgi-bin/2848/3/dedup.pl, body=LastName=Doe&FirstName=Jon
18:59:17.5608 HPSHTTPPost PostToUri has string response = Success
18:59:18.0295 HPSHTTPPost PostToUri has string response = Success
It seems that the Http Response is being received twice. Is this even technically possible? i.e. is it possible for an Http POST to receive two Responses, one after the other? If so, is my code below then liable to be called twice, thus resulting in the observed log file entries? Many thanks.
Edit:
In response to the comment that the logging code may be broken, here is the logging code:
public class Log
{
public static void WriteLog(string commandText)
{
string clientDBName = "test";
string username = "test";
try
{
string filePath = "c:\\Data\\XXXLogs\\" + clientDBName + "logs\\";
string filename = System.DateTime.Now.ToString("yyyyMMdd_") + username + ".log";
DirectoryInfo dir = new DirectoryInfo(filePath);
if (!dir.Exists)
{
dir.Create();
}
System.IO.FileStream stream = new System.IO.FileStream(
filePath + filename
, System.IO.FileMode.Append); // Will create if not already exists
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(); // Writes a line terminator, thus separating entries by 1 blank line
writer.WriteLine(System.DateTime.Now.ToString("HH:mm:ss.ffff") + " " + commandText);
writer.Flush();
stream.Close();
}
catch { }
}
}

generate pdf file from jasper report with servlet java code

I have a jasper report, I put it in the same package as servlets, I need to generate pdf file from it, but the code doesn't work and doesn't gives any error
public void print(String numBac , HttpServletRequest request,
HttpServletResponse response) {
try {
JasperDesign jasperDesign = JRXmlLoader
.load("fiche.jrxml");
String sql = "SELECT * FROM etudiant "
+ "INNER JOIN filiere ON etudiant.code_f=filiere.code_f "
+ "INNER JOIN lieu_nais ON etudiant.code_lieu=lieu_nais.code_lieu "
+ "INNER JOIN montant ON etudiant.code_m=montant.code_m WHERE bac='"
+ numBac + "'";
JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(sql);
jasperDesign.setQuery(newQuery);
JasperReport report = JasperCompileManager
.compileReport(jasperDesign);
//JasperPrint print = JasperFillManager.fillReport(report, null, cnx);
//JasperViewer.viewReport(print);
byte[] byteStream;
byteStream = JasperRunManager.runReportToPdf(report, null, cnx);
OutputStream outStream = response.getOutputStream();
response.setHeader("Content-Sisposition", "inline,filename="+DOWNLOAD_FILE_NAME);
response.setContentType(FILE_TYPE);
response.setContentLength(byteStream.length);
outStream.write(byteStream, 0, byteStream.length);
} catch (Exception e) {
e.printStackTrace();
}
}
even if I want to generate jasper preview it doesn't shown up (code in comment)
What is baos for? Do you have to flush/close sos?
You can use bellow code. Here is complete Example using java servlet
Please download bellow jar file..
jasperreports-5.0.1.jar
commons-logging-1.1.2.jar
commons-digester-2.1.jar
commons-collections-3.2.1-1.0.0.jar
commons-beanutils-1.8.3.jar
groovy-all-2.1.3.jar
com.lowagie.text-2.1.7.jar
your database library
You can use like
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String path = "D:\\Software\\iReport-5.0.0-windows-installer\\u\\report4.jrxml";
JasperReport jasReport = JasperCompileManager.compileReport(path);
System.out.println("Jasper Report : " + jasReport);
//Database connection
Connection con = /*Database Connection*/;
System.out.println(con);
//If You have any Paramert use bellow like
Map paramMap = new HashMap();
paramMap.put("id", request.getParameter("id"));
//If You don't have parameter pass null instead of paramMap
JasperPrint jasPrint = JasperFillManager.fillReport(jasReport, paramMap, con);
System.out.println("Jasper Print : " + jasPrint);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ServletOutputStream sos = response.getOutputStream();
response.setContentType("application/pdf");
JasperExportManager.exportReportToPdfStream(jasPrint, sos);
} catch (JRException ex) {
Logger.getLogger(Tests.class.getName()).log(Level.SEVERE, null, ex);
}
}
First of all, you have a spelling error here:
response.setHeader("Content-Sisposition", "inline,filename="+DOWNLOAD_FILE_NAME);
It should say "Disposition" instead of "Sisposition":
response.setHeader("Content-Disposition", "inline,filename="+DOWNLOAD_FILE_NAME);
Also, try using "attachment" instead of "inline":
response.setHeader("Content-Disposition", "attachment,filename="+DOWNLOAD_FILE_NAME);
And flush and close the outStream:
outStream.flush();
outStream.close();
Hope it helps!

Can't download file. Browser opens it instead.

I have tried a lot of contentTypes and headers I have seen here but still can't figure out what I am doing wrong. I have the following Spring Controller:
#RequestMapping(value = "/anexo/{id}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<String> getAnexoById(#PathVariable int id, HttpServletResponse response) {
Anexo a = anexoDAO.getAnexo(id);
if (a == null)
return new ResponseEntity<String>(HttpStatusMessage.NOT_FOUND, HttpStatus.NOT_FOUND);
else {
try {
File dir = new File("temp");
if (!dir.exists())
dir.mkdirs();
String filePath = dir.getAbsolutePath() + File.separator + a.getName();
File serverFile = new File(filePath);
FileInputStream fistream = new FileInputStream(serverFile);
org.apache.commons.io.IOUtils.copy(fistream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename=" + a.getName());
response.setContentType("application/octet-stream");
response.setHeader("Content-Length", String.valueOf(serverFile.length()));
response.setHeader("Content-Transfer-Encoding", "binary");
response.flushBuffer();
System.out.println(response.toString());
return new ResponseEntity<String>(HttpStatus.OK);
} catch (IOException ex) {
return new ResponseEntity<String>("Exception on getting file", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
I also have tried with and without #ResponseBody.
The user will be able to upload any type of file to the server and then he will be able to download through this controller. The problem is that instead of the download window, the browser open the file in the page. How can I make it download?
Thanks in advance
This work for me:
#ResponseBody
void getOne(#PathVariable("id") long id, HttpServletResponse response) throws IOException {
MyFile file = fileRepository.findOne(id);
if(file == null) throw new ResourceNotFoundException();
response.setContentType(file.getContentType());
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() +"\"");
response.setContentLength(file.getData().length);
FileCopyUtils.copy(file.getData(), response.getOutputStream());
}
Where MyFile is a class like this:
class MyFile {
private Long id;
private String contentType;
private String name;
private bit[] data;
...
}

Problem downloading a 25MB file - the 8MB file downloads without problem (ASP.NET)

I have two files at the same location but the big one, when is about to finish download, gives an error (both in IE and Firefox).
I use the following code:
public static void DownloadZipFile (string filename, bool notifyMe)
{
HttpContext context = HttpContext.Current;
HttpServerUtility server = context.Server;
bool ok = false;
try
{
string file = string.Format ("~/contents/licensing/members/downloads/{0}", filename);
string server_file = server.MapPath (file);
HttpResponse response = context.Response;
//response.BufferOutput = false;
response.ContentType = "application/zip";
string value = string.Format ("attachment; filename={0}", filename);
response.AppendHeader ("Content-Disposition", value);
FileInfo f = new FileInfo (server_file);
long size = f.Length;
response.TransmitFile (server_file, 0, size);
response.Flush ();
ok = true;
response.End ();
}
catch (Exception ex)
{
Utilities.Log (ex);
}
finally
{
if (ok && notifyMe)
NotifyDownload (filename);
}
}
Any ideas?
Response.End() calls Response.Flush(). Try removing the Flush call.
The solution to this problem is to add the line:
response.AddHeader("Content-Length",size.ToString());
before the call to TransmitFile ().
The credits go to Jim Schubert (see his comment above).

Resources