File Download ================================================================================ .. only:: html .. contents:: Table of Contents :depth: 3 :local: Overview -------------------------------------------------------------------------------- | This chapter explains the functionality to download a file from server to client, using Spring. | It is recommended to use Spring MVC View for rendering the files. \ .. note:: It is not recommended to include file rendering logic in controller class. This is because, it deviates from the role of a controller. Moreover, a View can be easily changed when it is isolated from the controller. Overview of File Download process is given below. #. DispatchServlet sends file download request to the controller. #. Controller fetches file display information. #. Controller selects View. #. File rendering is performed in View. | In order to perform file rendering in a Spring based Web application; | this guideline recommends implementation of custom view. | To implement custom view, ``org.springframework.web.servlet.View`` interface | is provided in Spring framework. | | **For PDF files** | \ ``org.springframework.web.servlet.view.document.AbstractPdfView``\ class of Spring is used as a subclass | when rendering PDF files using model information. | | **For Excel files** | \ ``org.springframework.web.servlet.view.document.AbstractXlsxView``\ class of Spring is used as a subclass | when rendering Excel files using model information. | | For file formats other than those specified above, various types of View implementations are provided in Spring. | For technical details on View, refer to \ `Spring Reference View technologies `_\ . | \ ``org.terasoluna.gfw.web.download.AbstractFileDownloadView``\ provided by common library is the | abstract class to download arbitrary files. | Define this class as a subclass to render files in formats other than PDF or Excel. .. tip:: A countermeasure for directory traversal attack may become necessary while offering a file download function. For directory traversal attack, refer \ :ref:`file-upload_security_related_warning_points_directory_traversal` \. | How to use -------------------------------------------------------------------------------- Downloading PDF files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | For rendering PDF files, it is necessary to create a class that | inherits \ ``org.springframework.web.servlet.view.document.AbstractPdfView``\ provided by Spring. | The procedure to download a PDF file using controller is explained below. Implementation of Custom View """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" **Implementation of class that inherits AbstractPdfView** .. code-block:: java @Component // (1) public class SamplePdfView extends AbstractPdfView { // (2) @Override protected void buildPdfDocument(Map model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception { // (3) document.add(new Paragraph((Date) model.get("serverTime")).toString()); } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | In this example, this class comes under the scope of component scanning by using \ ``@Component``\ annotation. | It will also come under the scope of \ ``org.springframework.web.servlet.view.BeanNameViewResolver``\ which is described later. * - | (2) - | Inherit \ ``AbstractPdfView``\ . * - | (3) - | Execute \ ``buildPdfDocument``\ method. | \ ``AbstractPdfView``\ uses \ `iText `_\ for PDF rendering. | Therefore, it is necessary to add itext definition to pom.xml of Maven. .. code-block:: xml com.lowagie itext xml-apis xml-apis bctsp-jdk14 org.bouncycastle jfreechart jfree dom4j dom4j org.swinglabs pdf-renderer org.bouncycastle bcprov-jdk14 org.bouncycastle bcprov-jdk14 1.38 \ .. note:: In the above setting example, since it is assumed that the dependent library version is managed by the parent project terasoluna-gfw-parent , specifying the version in pom.xml is not necessary. The above itext used by terasoluna-gfw-parent is defined by \ `Spring IO Platform `_\ . .. _viewresolver-label: Definition of ViewResolver """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ ``org.springframework.web.servlet.view.BeanNameViewResolver``\ is a class, that selects View to be executed using bean name stored in Spring context. When using \ ``BeanNameViewResolver``\ , it is recommended to define such that \ ``BeanNameViewResolver``\ is executed before * \ ``ViewResolver``\ for JSP (\ ``InternalResourceViewResolver``\ ) * \ ``ViewResolver``\ for Tiles (\ ``TilesViewResolver``\ ) which are generally used. .. note:: Spring Framework provides various types of \ ``ViewResolver``\ and it allows chaining of multiple \ ``ViewResolver``\ . Therefore, some unintended View may get selected under certain conditions. It is possible to avoid such a situation by setting appropriate priority order in \ ``ViewResolver``\ . Method to set priority order differs depending on definition method of \ ``ViewResolver``\ . * When defining \ ``ViewResolver``\ using \ ````\ element added from Spring Framework 4.1, definition order of \ ``ViewResolver``\ specified in child element will be the priority order. (executed sequentially from top) * When specifying \ ``ViewResolver``\ using \ ````\ element in a conventional way, set priority order in \ ``order``\ property. (It is executed starting from smallest setting value). | **bean definition file** .. code-block:: xml :emphasize-lines: 2 .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Define \ ``BeanNameViewResolver``\ using \ ````\ element added from Spring Framework 4.1. * - | (2) - | Define \ ````\ element right at the top so that it has a higher priority than the generally used \ ``ViewResolver``\ (\ ``ViewResolver``\ for JSP). .. tip:: \ ````\ element is an XML element added from Spring Framework 4.1. If \ ````\ element is used, it is possible to define \ ``ViewResolver`` \ in a simple way. Example of definition when \ ````\ element used in a conventional way is given below. .. code-block:: xml :emphasize-lines: 1-3 In \ ``order``\ property, specify a value that is lesser than \ ``InternalResourceViewResolver``\ to ensure that it gets a high priority. | Specifying View in controller """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | With the help of \ ``BeanNameViewResolver``\ , by returning "samplePDFView" in Controller, | a view named "samplePDFView" gets used from the BeanIDs stored in Spring Context. **Java source code** .. code-block:: java @RequestMapping(value = "home", params= "pdf", method = RequestMethod.GET) public String homePdf(Model model) { model.addAttribute("serverTime", new Date()); return "samplePdfView"; // (1) } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | With "samplePdfView" as the return value of method, | \ ``SamplePdfView``\ class stored in Spring context is executed. | Following PDF file can be opened after executing the above procedure. .. figure:: ./images/file-download-pdf.png :alt: FILEDOWNLOAD PDF :width: 60% :align: center **Picture - FileDownload PDF** | Downloading Excel files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | For rendering EXCEL files, it is necessary to create a class that | inherits \ ``org.springframework.web.servlet.view.document.AbstractXlsxView``\ provided by Spring. | The procedure to download an EXCEL file using controller is explained below. Implementation of Custom View """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" **Implementation of class that inherits AbstractXlsxView** .. code-block:: java @Component // (1) public class SampleExcelView extends AbstractXlsxView { // (2) @Override protected void buildExcelDocument(Map model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { // (3) Sheet sheet; Cell cell; sheet = workbook.createSheet("Spring"); sheet.setDefaultColumnWidth(12); // write a text at A1 cell = getCell(sheet, 0, 0); setText(cell, "Spring-Excel test"); cell = getCell(sheet, 2, 0); setText(cell, ((Date) model.get("serverTime")).toString()); } private Cell getCell(Sheet sheet, int rowNumber, int cellNumber) { Row row = sheet.createRow(rowNumber); return row.createCell(cellNumber); } private void setText(Cell cell, String text) { cell.setCellValue(text); } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | In this example, this class comes under the scope of component scanning by using \ ``@Component``\ annotation. | It will also come under the scope of \ ``org.springframework.web.servlet.view.BeanNameViewResolver``\ which is described earlier. * - | (2) - | Inherit \ ``AbstractXlsxView``\ . * - | (3) - | Execute \ ``buildExcelDocument``\ method. | \ ``AbstractXlsxView``\ uses \ `Apache POI `_\ to render EXCEL file. | Therefore, it is necessary to add POI definition to the pom.xml file of Maven. .. code-block:: xml org.apache.poi poi-ooxml stax stax-api \ .. note:: Since stax-api on which poi-ooxml is dependent, is provided as a standard from SE, the library is not required. Also, since a conflict is likely in the library, \ ````\ element should be added and the relevant library should not be added in the application. \ .. note:: In the above setting example, since it is assumed that the dependent library version is managed by the parent project terasoluna-gfw-parent , specifying the version in pom.xml is not necessary. The above dependent library used by terasoluna-gfw-parent is defined by \ `Spring IO Platform `_\ . Also, \ ``AbstractExcelView``\ uses @Deprecated annotation from Spring Framework 4.2. Hence, it is recommended to use \ ``AbstractXlsxView``\ in the same way even if you want to use a xls file. For details, refer \ `AbstractExcelView - JavaDoc `_\ . Definition of ViewResolver """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Settings are same as that for PDF file rendering. For details, refer to \ :ref:`viewresolver-label`\ . Specifying View in controller """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | With the help of \ ``BeanNameViewResolver``\ , by returning "sampleExcelView" in Controller, | a view named "sampleExcelView" gets used from the BeanIDs stored in Spring Context. **Java source** .. code-block:: java @RequestMapping(value = "home", params= "excel", method = RequestMethod.GET) public String homeExcel(Model model) { model.addAttribute("serverTime", new Date()); return "sampleExcelView"; // (1) } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | With "sampleExcelView"as the return value of method, | \ ``SampleExcelView``\ class stored in Spring context is executed. | EXCEL file can be opened as shown below after executing the above procedures. .. figure:: ./images/file-download-excel.png :alt: FILEDOWNLOAD EXCEL :width: 60% :align: center **Picture - FileDownload EXCEL** Downloading arbitrary files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | To download files in formats other than PDF or EXCEL, | class that inherits \ ``org.terasoluna.gfw.web.download.AbstractFileDownloadView``\ provided by common library can be implemented. | Following steps should be implemented in \ ``AbstractFileDownloadView``\ to render files in other format. 1. Fetch InputStream in order to write to the response body. 2. Set information in HTTP header. | How to implement file download using controller is explained below. Implementation of Custom View """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | The example of text file download is given below. **Implementation of class that inherits AbstractFileDownloadView** .. code-block:: java @Component // (1) public class TextFileDownloadView extends AbstractFileDownloadView { // (2) @Override protected InputStream getInputStream(Map model, HttpServletRequest request) throws IOException { // (3) Resource resource = new ClassPathResource("abc.txt"); return resource.getInputStream(); } @Override protected void addResponseHeader(Map model, HttpServletRequest request, HttpServletResponse response) { // (4) response.setHeader("Content-Disposition", "attachment; filename=abc.txt"); response.setContentType("text/plain"); } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | In this example, this class comes under the scope of component scanning by using \ ``@Component``\ annotation. | It will also come under the scope of \ ``org.springframework.web.servlet.view.BeanNameViewResolver``\ which is described earlier. * - | (2) - | Inherit \ ``AbstractFileDownloadView``\ . * - | (3) - | Execute \ ``getInputStream``\ method. | \ ``InputStream``\ to be downloaded should be returned. * - | (4) - | Execute \ ``addResponseHeader method``\ . | Set Content-Disposition or ContentType as per the file to be downloaded. Definition of ViewResolver """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Settings are same as that of PDF file rendering. For details, refer to \ :ref:`viewresolver-label`\ . Specifying View in controller """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | With the help of \ ``BeanNameViewResolver``\ , by returning "textFileDownloadView" in Controller, | a view named "textFileDownloadView" gets used from the BeanIDs stored in Spring Context. **Java source** .. code-block:: java @RequestMapping(value = "download", method = RequestMethod.GET) public String download() { return "textFileDownloadView"; // (1) } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | With "textFileDownloadView"as the return value of method, | \ ``TextFileDownloadView``\ class stored in Spring context is executed. \ .. tip:: As described above, Model information can be rendered in various types of Views using Spring. Spring supports rendering engine such as Jasper Reports and returns various types of views. For details, refer to the official Spring website \ `Spring reference `_\ . .. raw:: latex \newpage