Seam application using tomcat and postgresql 9.0.3
App allows users to download word documents that are saved in the DB as BLOB and defined in the bean as a byte array.
These word documents have been uploaded by users in xml format.
When I use this code with Tomcat(5) in Windows, it works just fine. When used with Tomcat (v. 6.0.24) on a Linux server, I get the behavior that the contents are displayed as HEX code in the Downloaded file???
At first I thought that the server was missing some fonts, files with Fonts that are definitely on the server show the same behavior. Even TXT files do the same thing.
The code for doing the download is as follows:
byte[] wordDoc = createApptLetter();
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType("application/msword");
fileName = letter.getFileName();
response.addHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
response.setContentLength(wordDoc.length);
OutputStream os = response.getOutputStream();
//log.error(response.getContentType());
os.write(wordDoc);
os.flush();
os.close();
facesContext.renderResponse();
facesContext.responseComplete();
edit: here is createApptLetter method:
private byte[] createApptLetter() {
LetterTemplate template = appointmentHome.getInstance().getLetterTemplate();
Client client = appointmentHome.getInstance().getClientRegistration().getEligibilityCycle().getClient();
String sageClinic = appointmentHome.getInstance().getFacility().getName();
String apptDate = appointmentHome.getInstance().getAppointmentDateString();
String apptTime = appointmentHome.getInstance().getAppointmentTimeString();
String notes = appointmentHome.getInstance().getAppointmentNotes();
String longDateFormat = SageConstantsEnum.DateFormats.LONGDATEFORMAT.getDescription();
SimpleDateFormat df = new SimpleDateFormat(longDateFormat);
String today = df.format(new Date());
//StringBuilder sbTemplate = new StringBuilder(new String(template.getLetterTemplateText()));
String xmlTemplate = new String (template.getLetterTemplateText());
xmlTemplate = xmlTemplate.replace("letterDate", today);
xmlTemplate = xmlTemplate.replace("apptDate", apptDate);
xmlTemplate = xmlTemplate.replace("apptTime", apptTime);
xmlTemplate = xmlTemplate.replace("apptNotes", notes);
xmlTemplate = xmlTemplate.replace("sageClinic", sageClinic);
xmlTemplate = xmlTemplate.replace("clientName", client.getFullname());
xmlTemplate = xmlTemplate.replace("clientCity",client.getMailingAddress().getAddress().getCity());
xmlTemplate = xmlTemplate.replace("clientAddress", client.getMailingAddress().getAddress().getStreetaddress());
xmlTemplate = xmlTemplate.replace("clientState",client.getMailingAddress().getAddress().getState());
xmlTemplate = xmlTemplate.replace("clientZip", client.getMailingAddress().getAddress().getZipcode());
return xmlTemplate.getBytes();
}
Change the content type of your response to "application/octet-stream". This works for any kind of file. There is an example with JSF. In my example, I'm using a a4j:htmlCommandLink from RichFaces, since you're using Seam i guess you won't have any problem.
Related
I have a rest api which allows me to pass multiple IDS to a resource to download records from specific table and zip it. MSSQL is the backend mastering messages.
So when a ID is passed as param, it calls the database table to return the message data. Below is the code:
#GetMapping("message/{ids}")
public void downloadmessage(#PathVariable Long[] ids, HttpServletResponse response) throws Exception {
List<MultiplemessageID> multiplemessageID = auditRepository.findbyId(ids);
String xml = new ObjectMapper().writeValueAsString(MultiplemessageID);
String fileName = "message.zip";
String xml_name = "message.xml";
byte[] data = xml.getBytes();
byte[] bytes;
try (ByteOutputStream bout = new ByteOutputStream(); ZipOutputStream zout = new ZipOutputStream(bout)) {
for (Long id : ids) {
zout.setLevel(1);
ZipEntry ze = new ZipEntry(xml_name);
ze.setSize(data.length);
ze.setTime(System.currentTimeMillis());
zout.putNextEntry(ze);
zout.write(data);
zout.closeEntry();
}
bytes = bout.getBytes();
}
response.setContentType("application/zip");
response.setContentLength(bytes.length);
response.setHeader("Content-Disposition", "attachment; " + String.format("filename=" + fileName));
ServletOutputStream outputStream = response.getOutputStream();
FileCopyUtils.copy(bytes, outputStream);
outputStream.close();
}
Message on the database has the following structure:
MSG_ID C_ID NAME INSERT_TIMESTAMP MSG CONF F_NAME POS ID INB HEADERS
0011d540 EDW,WSO2,AS400 invoicetoedw 2019-08-29 23:59:13 <invoice>100923084207</invoice> [iden1:SMTP, iden2:SAP, service:invoicetoedw, clients:EDW,WSO2,AS400, file.path:/c:/nfs/store/invoicetoedw/output, rqst.message.format:XML,] p3_pfi_1 Pre 101 MES_P3_IN [clients:EDW,WSO2,AS400, UniqueName:Domain]
My file name should be like: part of header name + _input parameterId[0]
i.e. Domain_1
File name for multiple paramter (1,2,3,4)will be like
Domain_1
Domain_2
Domain_3
Domain_4
Below code retrieves the part of file name as string from the header.
private static String serviceNameHeadersToMap(String headers) {
String sHeaders = headers.replace("[", "");
sHeaders = sHeaders.replace("]", "");
String res = Arrays.stream(sHeaders.split(", "))
.filter(s->s.contains("serviceNameIdentifier"))
.findFirst()
.map(name->name.split(":")[1])
.orElse("Not Present");
return res;
I need to create a file name with header and input parameter. Once the file name is set, I would like individual records downloaded with correct file name and zipped.
Zip file name is message.zip. When unzipped it should contain individual files like Domain_1.xml, Domain_2.xml, Domain_3.xml, Domain_4.xml etc...
How do I achieve this? Please advise. I need some guidance for the limited knowledge on java I have. Thank you.
I'm trying to download a ZIP file with HTMLUnit 2.32 using the following code.
I obtain a "myfile.zip" bigger than the one downloaded through a normal browser (179kb vs 79kb) and which is corrupt.
How one should click an anchor and download a file with HTMLUnit?
WebClient wc = new WebClient(BrowserVersion.CHROME);
final String HREF_SCARICA_CONSOLIDATI = "/web/area-pubblica/quotate?viewId=export_quotate";
final String CONSOBBase = "http://www.consob.it";
HtmlPage page = wc.getPage(CONSOBBase + HREF_SCARICA_CONSOLIDATI);
final String downloadButtonXpath = "//a[contains(#href, 'javascript:downloadAzionariato()')]";
List<HtmlAnchor> downloadAnchors = page.getByXPath(downloadButtonXpath);
HtmlAnchor downloadAnchor = downloadAnchors.get(0);
UnexpectedPage downloadedFile = downloadAnchor.click();
InputStream contentAsStream = downloadedFile.getWebResponse().getContentAsStream();
File destFile = new File("/tmp", "myfile.zip");
Writer out = new OutputStreamWriter(new FileOutputStream(destFile));
IOUtils.copy(contentAsStream, out);
out.close();
Have updated your code snippet a bit to make it work. Hope the inline comments are helping a bit to understand what is going on (using the latest SNAPSHOT code of HtmlUnit (2.34-SNAPSHOT 2018/11/03)
final String HREF_SCARICA_CONSOLIDATI = "http://www.consob.it/web/area-pubblica/quotate?viewId=export_quotate";
try (final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_60)) {
HtmlPage page = webClient.getPage(HREF_SCARICA_CONSOLIDATI);
final String downloadButtonXpath = "//a[contains(#href, 'javascript:downloadAzionariato()')]";
List<HtmlAnchor> downloadAnchors = page.getByXPath(downloadButtonXpath);
HtmlAnchor downloadAnchor = downloadAnchors.get(0);
// click does some javascript magic - have a look at your browser
// seems like this opens a new window with the content as response
// because of this we can ignore the page returned from click
downloadAnchor.click();
// instead of we are waiting a bit until the javascript is done
webClient.waitForBackgroundJavaScript(1000);
// now we have to pick up the window/page that was opened as result of the download
Page downloadPage = webClient.getCurrentWindow().getEnclosedPage();
// and finally we can save to content
File destFile = new File("/tmp", "myfile.zip");
try (InputStream contentAsStream = downloadPage.getWebResponse().getContentAsStream()) {
try (OutputStream out = new FileOutputStream(destFile)) {
IOUtils.copy(contentAsStream, out);
}
}
System.out.println("Output written to " + destFile.getAbsolutePath());
}
While RBRi considerations are interesting, I discovered my code worked with HTMLUnit 2.32 with no modifications but I was writing the file the wrong way!
I used
Writer out = new OutputStreamWriter(new FileOutputStream(destFile));
IOUtils.copy(contentAsStream, out);
while it had to be (no OutputStreamWriter)
FileOutputStream out = new FileOutputStream(destFile);
IOUtils.copy(contentAsStream, out);
I am using xDoc report to generate PDF by giving the docx file as input. everything is fine when I used English docx file, when I used my other language docx file I couldn't get the pdf as readable.
here is my code..
File fil = new File(
"/home/madurauser/analyzer/LOS/DocxProjectWithVelocity1.docx");
FileInputStream in = new FileInputStream(fil);
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(
in, TemplateEngineKind.Velocity);
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsList("developers.Inst");
metadata.addFieldAsList("developers.MBalance");
metadata.addFieldAsList("developers.MDemand");
metadata.addFieldAsList("developers.MInterest");
metadata.addFieldAsList("developers.MPrincipal");
metadata.addFieldAsList("developers.GBalance");
metadata.addFieldAsList("developers.GDemand");
metadata.addFieldAsList("developers.GInterest");
metadata.addFieldAsList("developers.GPrincipal");
metadata.addFieldAsList("developers.Members");
metadata.addFieldAsList("developers.Month");
report.setFieldsMetadata(metadata);
IContext context = report.createContext();
List<Developer> developers = new ArrayList<Developer>();
List<LoanRepaymentSchedule> repay = this.loanService
.getLoanRepaymentScheduleById(groupLoan.getLoanId()
.longValue());
LoanRepaymentSchedule rep = repay.get(repay.size() - 1);
Project project = new Project(lt, loan.getGroupName(),
lastFiveDigitsAccNo, groupDto.getVillageName(),
groupDto.getCluster(), groupDto.getClusterCentre(),
groupDto.getRegion(), intLoanAmount, loan.getLoanAccNo(),
Long.valueOf(loan.getLoanInstallments()),
loan.getGroupId(), decIntRate, loan.getAnimator(),
loan.getRep1(), loan.getRep2(), noOfDays, brokenPeriod,
sanctionDate, lastFiveDigitsAccNo, strSancDate,
rep.getMemberCount());
context.put("project", project);
for (Iterator iterator = repay.iterator(); iterator.hasNext();) {
LoanRepaymentSchedule loanRepaymentSchedule = (LoanRepaymentSchedule) iterator
.next();
String month;
Integer year = loanRepaymentSchedule.getYear();
Integer formattedDate = year % 100;
developers.add(new Developer(intgBal, intgDem, intgInt,
intgPri, intmBal, intmDem, intmInt, intmPri, month,
loanRepaymentSchedule.getMemberCount(),
loanRepaymentSchedule.getMemberCount(),
loanRepaymentSchedule.getSerialNo()));
context.put("developers", developers);
}
// OutputStream out = new FileOutputStream(new File(conv+".pdf"));
OutputStream out = new FileOutputStream(new File(files + "_" + groupID
+ ".pdf"));
Options options = Options.getTo(ConverterTypeTo.PDF).via(
ConverterTypeVia.XWPF);
report.convert(context, options, out);
This is my tamil font docx and gave as a input
The generated output looks like below.
Any ideas in this would be appreciated.
I have a servlet witch is generating a .xls file and then it's sending the generated file to the user for download with the code below:
// Write the output to a file
Calendar currentDate = Calendar.getInstance();
SimpleDateFormat formatter=
new SimpleDateFormat("yyyy_MMM_dd");
String dateNow = formatter.format(currentDate.getTime());
String path = "webapps/myapp/exports/";
String fileName = ("Table_export_"+ dateNow + ".xls");
FileOutputStream fileOut = new FileOutputStream(path+fileName);
wb.write(fileOut);
fileOut.close();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment;filename="+fileName);
The file is saved on the server with a size of 5 kb, but after the browser dialog and after choosing save or open, the file is empty and the size is 0 kb. I can not understand what is wrong.
I'm fighting with this issue for about 2 hours without a success. I have tried to set the full path:
response.setHeader("Content-Disposition","attachment;filename="path+fileName);
But I got a document with a strange name and it also was 0 kb.
I'm pretty sure that I'm missing something really small, but as a junior developer I still can not figure it out.
Since you already have a method that can write your file to an output stream you can simply change your code this way to send it to the user :
Calendar currentDate = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MMM_dd");
String dateNow = formatter.format(currentDate.getTime());
String fileName = ("Table_export_"+ dateNow + ".xls");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment;filename="+fileName);
OutputStream outputStream = response.getOutputStream();
try {
wb.write(outputStream);
} finally {
outputStream.close();
}
It won't be saved on your server HDD though.
The method HttpServletResponse#getOutputStream() allows you to access the stream of bytes that will be sent back to the client.
When you used the format -
String path = "webapps/myapp/exports/";
String fileName = ("Table_export_"+ dateNow + ".xls");
...
response.setHeader("Content-Disposition","attachment;filename="path+fileName);
Was the filename "webapps%2Fmyapps%2Fexports%2fTable_export_....xls"?
Als the filesize would have been zero because you are not putting any data in the file
I have a servlet which is responsible for enabling a user to update a reports table and upload a report at the same time. I have written code that enables a user upload a document and also be able to update the table with other details e.g date submitted etc.
However not all the times will a user have to upload a document. in this case it should be possible for a user to still edit a report's details and come back later to upload the file. i.e the user can submit the form without selecting a file and it still updates the table.
This part is what is not working. If a user selects a file and makes some changes. The code works. If a user doesn't select a file and tries to submit the form, it redirects to my servlet but it is blank. no stacktrace. No error is thrown.
Below is part of the code I have in my servlet:
if(param.equals("updateschedule"))
{
String[] allowedextensions = {"pdf","xlsx","xls","doc","docx","jpeg","jpg","msg"};
final String path = request.getParameter("uploadlocation_hidden");
final Part filepart=request.getPart("uploadreport_file");
int repid = Integer.parseInt(request.getParameter("repid_hidden"));
int reptype = Integer.parseInt(request.getParameter("reporttype_select"));
String webdocpath = request.getParameter("doclocation_hidden");
String subperiod = request.getParameter("submitperiod_select");
String duedate = request.getParameter("reportduedate_textfield");
String repname = request.getParameter("reportname_textfield");
String repdesc = request.getParameter("reportdesc_textarea");
String repinstr = request.getParameter("reportinst_textarea");
int repsubmitted = Integer.parseInt(request.getParameter("repsubmitted_select"));
String datesubmitted = request.getParameter("reportsubmitdate_textfield");
final String filename = getFileName(filepart);
OutputStream out = null;
InputStream filecontent=null;
String extension = filename.substring(filename.lastIndexOf(".") + 1, filename.length());
if(Arrays.asList(allowedextensions).contains(extension))
{
try
{
out=new FileOutputStream(new File(path+File.separator+filename));
filecontent = filepart.getInputStream();
int read=0;
final byte[] bytes = new byte[1024];
while((read=filecontent.read(bytes))!=-1)
{
out.write(bytes,0,read);
}
String fulldocpath = webdocpath+"/"+filename;
boolean succ = icreditdao.updatereportschedule(repid, reptype, subperiod, repname, repsubmitted,datesubmitted, duedate,fulldocpath, repdesc, repinstr);
if(succ==true)
{
response.sendRedirect("/webapp/Pages/Secured/ReportingSchedule.jsp?msg=Report Schedule updated successfully");
}
}
catch(Exception ex)
{
throw new ServletException(ex);
}
}
I'm still teaching myself javaee. Any help will be appreciated. Also open to other alternatives. I have thought of using jquery to detect if a file has been selected then use a different set of code. e.g
if(param.equals("updatewithnofileselected"))
{//update code here}
but I think there must be a better solution. Using jdk6, servlet3.0.
try this one.
MultipartParser parser = new MultipartParser(request, 500000000, false, false, "UTF-8");
Part part;
while ((part = parser.readNextPart()) != null) {
if(part.isParam()){
if(part.isFile()){
if(part.getName().equals("updatewithnofileselected")){
//update code here.
} else if(part.getName().equals("updateschedule")) {
//updateschedule
}
}
}
}
I used this one when I am using Multipart-form and it's working fine.