PDF generation using iText in Struts-2: result type stream not working

My requirement is to generate a PDF file using iText, I use the code below to create a PDF sample

Document document = new Document(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter.getInstance(document, baos); document.open(); document.add(new Paragraph("success PDF FROM STRUTS")); document.close(); ServletOutputStream outputStream = response.getOutputStream() ; baos.writeTo(outputStream); response.setHeader("Content-Disposition", "attachment; filename=\"stuReport.pdf\""); response.setContentType("application/pdf"); outputStream.flush(); outputStream.close(); 

If you see in the above code, iText does not use any inputStream parameter, rather, it writes directly to the response output stream. While struts-2 gives us the ability to use the InputStream parameter (see Configuration below)

 <action name="exportReport" class="com.export.ExportReportAction"> <result name="pdf" type="stream"> <param name="inputName">inputStream</param> <param name="contentType">application/pdf</param> <param name="contentDisposition">attachment;filename="sample.pdf"</param> <param name="bufferSize">1024</param> </result> </action> 

I know that my class must have getters and seters for inputStream, and I have this too in the class specified in struts-configuration

 private InputStream inputStream; public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } 

But since iText really does not need an input stream, but writes directly to the response output stream, I get exceptions because I do not set anything for the inputStream parameter.

Please let me know how to use iText code in struts-2 having resultType as stream

thanks

+4
source share
2 answers

The solution found.

The method in action that runs this PDF export may not be valid. Result type configuration is not required when we write directly to the response output stream

for example, create your action class

 Class ExportReportAction extends ActionSupport { public void exportToPdf() { // no return type try { Document document = new Document(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter.getInstance(document, baos); document.open(); document.add(new Paragraph("success PDF FROM STRUTS")); document.close(); ServletOutputStream outputStream = response.getOutputStream() ; baos.writeTo(outputStream); response.setHeader("Content-Disposition", "attachment; filename=\"stuReport.pdf\""); response.setContentType("application/pdf"); outputStream.flush(); outputStream.close(); }catch (Exception e) { //catch } } } 

and configure your struts

 <action name="exportReport" class="com.export.ExportReportAction"> <!-- NO NEED TO HAVE RESULT TYPE STREAM CONFIGURATION--> </action> 

it works great !!!

Thanks to everyone who tried to answer this question.

+4
source

The main answer:

You can also return NONE or return null as described in Apache docs:

Returning ActionSupport.NONE (or null) from the action class method causes a skipped result processing. This is useful if the action fully handles the processing of results, for example, the HttpServletResponse output stream itself.

Source: http://struts.apache.org/release/2.2.x/docs/result-configuration.html


Example:

O'Reilly offers a tutorial on Dynamically creating PDF files in a web application using a servlet (SC Sullivan, 2003). It can be converted to the Struts2 action class, as shown below.

It's nice to have a helper class like PDFGenerator to create a PDF file for you and return it as ByteArrayOutputStream .

PDFGenerator class :

 import java.io.ByteArrayOutputStream; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; public class PDFGenerator { public ByteArrayOutputStream generatePDF() throws DocumentException { Document doc = new Document(); ByteArrayOutputStream baosPDF = new ByteArrayOutputStream(); PdfWriter pdfWriter = PdfWriter.getInstance(doc, baosPDF); try { doc.open(); // create pdf here doc.add(new Paragraph("Hello World")); } catch(DocumentException de) { baosPDF.reset(); throw de; } finally { if(doc != null) { doc.close(); } if(pdfWriter != null) { pdfWriter.close(); } } return baosPDF; } } 

Now you can call it in your action class.

ViewPDFAction class :

 import java.io.ByteArrayOutputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.interceptor.ServletResponseAware; import com.yoursite.helper.PDFGenerator; import com.opensymphony.xwork2.ActionSupport; public class ViewPDFAction extends ActionSupport implements ServletResponseAware { private static final long serialVersionUID = 1L; private HttpServletResponse response; @Override public String execute() throws Exception { ByteArrayOutputStream baosPDF = new PDFGenerator().generatePDF(); String filename = "Your_Filename.pdf"; response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline; filename=" + filename); // open in new tab or window response.setContentLength(baosPDF.size()); OutputStream os = response.getOutputStream(); os.write(baosPDF.toByteArray()); os.flush(); os.close(); baosPDF.reset(); return NONE; // or return null } @Override public void setServletResponse(HttpServletResponse response) { this.response = response; } } 

web.xml

 <mime-mapping> <extension>pdf</extension> <mime-type>application/pdf</mime-type> </mime-mapping> 

struts.xml :

 <action name="viewpdf" class="com.yoursite.action.ViewPDFAction"> <!-- NO CONFIGURATION FOR RESULT NONE --> </action> 
+2
source

Source: https://habr.com/ru/post/1432290/


All Articles