5.18. ファイルダウンロード¶
目次
5.18.1. Overview¶
Note
コントローラクラスで、ファイルレンダリングのロジックを持たせることは推奨しない。
理由としては、コントローラの役割から逸脱するためである。 また、コントローラから分離することで、Viewの入れ替えが、容易にできる。
ファイルのダウンロード処理の概要を、以下に示す。
- DispatchServletは、コントローラへファイルダウンロードのリクエストを送信する。
- コントローラは、ファイル表示の情報を取得する。
- コントローラは、Viewを選択する。
- ファイルレンダリングは、Viewで行われる。
org.springframework.web.servlet.View
インタフェースを提供している。org.springframework.web.servlet.view.document.AbstractPdfView
org.springframework.web.servlet.view.document.AbstractExcelView
org.terasoluna.gfw.web.download.AbstractFileDownloadView
は、5.18.2. How to use¶
5.18.2.1. PDFファイルのダウンロード¶
org.springframework.web.servlet.view.document.AbstractPdfView
を継承したクラスを作成する必要がある。5.18.2.1.1. カスタムViewの実装¶
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());
}
}
項番 | 説明 |
---|---|
(1)
|
本例では、
@Component アノテーションを使用して、component-scanの対象としている。後述する、
org.springframework.web.servlet.view.BeanNameViewResolver の対象とすることができる。 |
(2)
|
AbstractPdfViewを継承する。
|
(3)
|
buildPdfDocumentメソッドを実装する。
|
<dependencies>
<!-- omitted -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>${com.lowagie.itext.version}</version>
<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>
</exclusions>
</dependency>
</dependencies>
<properties>
<!-- omitted -->
<com.lowagie.itext.version>4.2.1</com.lowagie.itext.version>
</properties>
Note
Spring 3.2では、itextの5系のバージョンに対応していない。
5.18.2.1.2. ViewResolverの定義¶
org.springframework.web.servlet.view.BeanNameViewResolver
とは、Springのコンテキストで管理された、bean名を用いて実行するViewを選択するクラスである。order
プロパティを設定して、通常使用するInternalResourceViewResolver
より先に呼ばれるようにする必要がある。Note
Spring はさまざまなView Resolverを提供している。複数のResolverをチェーンすることができるため、特定の状況では、意図しないViewが選択されてしまうことがある。 それを防ぐために orderプロパティを指定することで、優先順位を設定できる。 orderプロパティの指定値が低いほど、先に実行される。
bean定義ファイル
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <!-- (1) -->
<property name="order" value="0"/> <!-- (2) -->
</bean>
項番 | 説明 |
---|---|
(1)
|
BeanNameViewResolver を定義する。
|
(2)
|
orderプロパティに0を設定する。InternalResourceViewResolverより、優先度を高くすること。
|
5.18.2.1.3. コントローラでのViewの指定¶
Javaソースコード
@RequestMapping(value = "home", params= "pdf", method = RequestMethod.GET)
public String homePdf(Model model) {
model.addAttribute("serverTime", new Date());
return "samplePdfView"; // (1)
}
項番 | 説明 |
---|---|
(1)
|
“samplePdfView” をメソッドの戻り値として返却することで、
Springのコンテキストで管理された、SamplePdfViewクラスが実行される。
|
5.18.2.2. Excelファイルのダウンロード¶
org.springframework.web.servlet.view.document.AbstractExcelView
を継承したクラスを作成する必要がある。5.18.2.2.1. カスタムViewの実装¶
AbstractExcelViewを継承したクラスの実装例
@Component // (1)
public class SampleExcelView extends AbstractExcelView { // (2)
@Override
protected void buildExcelDocument(Map<String, Object> model,
HSSFWorkbook workbook, HttpServletRequest request,
HttpServletResponse response) throws Exception { // (3)
HSSFSheet sheet;
HSSFCell 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());
}
}
項番 | 説明 |
---|---|
(1)
|
本例では、
@Component アノテーションを使用して、component-scanの対象としている。前述した、
org.springframework.web.servlet.view.BeanNameViewResolver の対象とすることができる。 |
(2)
|
AbstractExcelViewを継承する。
|
(3)
|
buildExcelDocumentメソッドを実装する。
|
<dependencies>
<!-- omitted -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${org.apache.poi.poi.version}</version>
</dependency>
</dependencies>
<properties>
<!-- omitted -->
<org.apache.poi.poi.version>3.9</org.apache.poi.poi.version>
</properties>
5.18.2.2.2. ViewResolverの定義¶
設定は、PDFファイルをレンダリングする場合と同様である。詳しくは、ViewResolverの定義を参照されたい。
5.18.2.2.3. コントローラでのViewの指定¶
Javaソース
@RequestMapping(value = "home", params= "excel", method = RequestMethod.GET)
public String homeExcel(Model model) {
model.addAttribute("serverTime", new Date());
return "sampleExcelView"; // (1)
}
項番 | 説明 |
---|---|
(1)
|
“sampleExcelView” をメソッドの戻り値として返却することで、
Springのコンテキストで管理された、SampleExcelViewクラスが実行される。
|
5.18.2.3. 任意のファイルのダウンロード¶
org.terasoluna.gfw.web.download.AbstractFileDownloadView
を継承したクラスを実装すればよい。- レスポンスボディへの書き込むためのInputStreamを取得する。
- HTTPヘッダに情報を設定する。
5.18.2.3.1. カスタムViewの実装¶
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");
}
}
項番 | 説明 |
---|---|
(1)
|
本例では、
@Component アノテーションを使用して、component-scanの対象としている。前述した、
org.springframework.web.servlet.view.BeanNameViewResolver の対象とすることができる。 |
(2)
|
AbstractFileDownloadViewを継承する。
|
(3)
|
getInputStreamメソッドを実装する。
ダウンロード対象の、InputStreameを返却すること。
|
(4)
|
addResponseHeaderメソッドを実装する。
ダウンロードするファイルに合わせた、 Content-Dispositionや、ContentTypeを設定する。
|
5.18.2.3.2. ViewResolverの定義¶
設定は、PDFファイルをレンダリングする場合と同様である。詳しくは、ViewResolverの定義を参照されたい。
5.18.2.3.3. コントローラでのViewの指定¶
Javaソース
@RequestMapping(value = "download", method = RequestMethod.GET)
public String download() {
return "textFileDownloadView"; // (1)
}
項番 | 説明 |
---|---|
(1)
|
“textFileDownloadView” をメソッドの戻り値として返却することで、
Springのコンテキストで管理された、TextFileDownloadViewクラスが実行される。
|
Tip
前述してきたように、SpringはModelの情報をいろいろなViewにレンダリングすることができる。 Springでは、Jasper Reportsのようなレンダリングエンジンをサポートし、さまざまなViewを返却することも可能である。 詳細は、Spring の公式ドキュメントSpring referenceを参照されたい。