4.10. File Download¶
Table of Contents
4.10.1. Overview¶
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.
org.springframework.web.servlet.View
interfaceorg.springframework.web.servlet.view.document.AbstractPdfView
class of Spring is used as a subclassorg.springframework.web.servlet.view.document.AbstractXlsxView
class of Spring is used as a subclassorg.terasoluna.gfw.web.download.AbstractFileDownloadView
provided by common library is theTip
A countermeasure for directory traversal attack may become necessary while offering a file download function. For directory traversal attack, refer Directory traversal attack .
4.10.2. How to use¶
4.10.2.1. Downloading PDF files¶
org.springframework.web.servlet.view.document.AbstractPdfView
provided by Spring.4.10.2.1.1. Implementation of Custom View¶
Implementation of class that inherits AbstractPdfView
@Component // (1)
public class SamplePdfView extends AbstractPdfView { // (2)
@Override
protected void buildPdfDocument(Map<String, Object> model,
Document document, PdfWriter writer, HttpServletRequest request,
HttpServletResponse response) throws Exception { // (3)
document.add(new Paragraph((Date) model.get("serverTime")).toString());
}
}
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.<dependencies>
<!-- omitted -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
<exclusion>
<artifactId>bctsp-jdk14</artifactId>
<groupId>org.bouncycastle</groupId>
</exclusion>
<exclusion>
<artifactId>jfreechart</artifactId>
<groupId>jfree</groupId>
</exclusion>
<exclusion>
<artifactId>dom4j</artifactId>
<groupId>dom4j</groupId>
</exclusion>
<exclusion>
<groupId>org.swinglabs</groupId>
<artifactId>pdf-renderer</artifactId>
</exclusion>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk14</artifactId>
<version>1.38</version>
</dependency>
</dependencies>
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.
4.10.2.1.2. 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<mvc:view-resolvers>
element added from Spring Framework 4.1, definition order ofViewResolver
specified in child element will be the priority order. (executed sequentially from top) - When specifying
ViewResolver
using<bean>
element in a conventional way, set priority order inorder
property. (It is executed starting from smallest setting value).
bean definition file
<mvc:view-resolvers>
<mvc:bean-name /> <!-- (1) (2) -->
<mvc:jsp prefix="/WEB-INF/views/" />
</mvc:view-resolvers>
Sr. No. | Description |
---|---|
(1)
|
Define
BeanNameViewResolver using <mvc:bean-name> element added from Spring Framework 4.1. |
(2)
|
Define
<mvc:bean-name> element right at the top so that it has a higher priority than the generally used ViewResolver (ViewResolver for JSP). |
Tip
<mvc:view-resolvers>
element is an XML element added from Spring Framework 4.1.
If <mvc:view-resolvers>
element is used, it is possible to define ViewResolver
in a simple way.
Example of definition when <bean>
element used in a conventional way is given below.
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="0"/> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> <property name="order" value="1" /> </bean>
In order
property, specify a value that is lesser than InternalResourceViewResolver
to ensure that it gets a high priority.
4.10.2.1.3. Specifying View in controller¶
BeanNameViewResolver
, by returning “samplePDFView” in Controller,Java source code
@RequestMapping(value = "home", params= "pdf", method = RequestMethod.GET)
public String homePdf(Model model) {
model.addAttribute("serverTime", new Date());
return "samplePdfView"; // (1)
}
Sr. No. | Description |
---|---|
(1)
|
With “samplePdfView” as the return value of method,
SamplePdfView class stored in Spring context is executed. |
4.10.2.2. Downloading Excel files¶
org.springframework.web.servlet.view.document.AbstractXlsxView
provided by Spring.4.10.2.2.1. Implementation of Custom View¶
Implementation of class that inherits AbstractXlsxView
@Component // (1)
public class SampleExcelView extends AbstractXlsxView { // (2)
@Override
protected void buildExcelDocument(Map<String, Object> 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);
}
}
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.<dependencies>
<!-- omitted -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<exclusions>
<exclusion>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
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,
<exclusions>
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 useAbstractXlsxView
in the same way even if you want to use a xls file. For details, refer AbstractExcelView - JavaDoc.
4.10.2.2.2. Definition of ViewResolver¶
Settings are same as that for PDF file rendering. For details, refer to Definition of ViewResolver.
4.10.2.2.3. Specifying View in controller¶
BeanNameViewResolver
, by returning “sampleExcelView” in Controller,Java source
@RequestMapping(value = "home", params= "excel", method = RequestMethod.GET)
public String homeExcel(Model model) {
model.addAttribute("serverTime", new Date());
return "sampleExcelView"; // (1)
}
Sr. No. | Description |
---|---|
(1)
|
With “sampleExcelView”as the return value of method,
SampleExcelView class stored in Spring context is executed. |
4.10.2.3. Downloading arbitrary files¶
org.terasoluna.gfw.web.download.AbstractFileDownloadView
provided by common library can be implemented.AbstractFileDownloadView
to render files in other format.- Fetch InputStream in order to write to the response body.
- Set information in HTTP header.
4.10.2.3.1. Implementation of Custom View¶
Implementation of class that inherits AbstractFileDownloadView
@Component // (1)
public class TextFileDownloadView extends AbstractFileDownloadView { // (2)
@Override
protected InputStream getInputStream(Map<String, Object> model,
HttpServletRequest request) throws IOException { // (3)
Resource resource = new ClassPathResource("abc.txt");
return resource.getInputStream();
}
@Override
protected void addResponseHeader(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) { // (4)
response.setHeader("Content-Disposition",
"attachment; filename=abc.txt");
response.setContentType("text/plain");
}
}
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.
|
4.10.2.3.2. Definition of ViewResolver¶
Settings are same as that of PDF file rendering. For details, refer to Definition of ViewResolver.
4.10.2.3.3. Specifying View in controller¶
BeanNameViewResolver
, by returning “textFileDownloadView” in Controller,Java source
@RequestMapping(value = "download", method = RequestMethod.GET)
public String download() {
return "textFileDownloadView"; // (1)
}
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.