Spring BootでJSONやExcelファイルを返すエンドポイントを作ってみる
「Spring Bootで簡単なWebアプリケーションを書いてみる」では、Spring Bootで簡単なWebアプリケーションを書いた。 ここでは作成したアプリケーションをベースに、APIとしてJSONを返したり、Excelファイルとしてダウンロードするエンドポイントを作ってみる。
環境
Windows 10 Pro、Java SE 8、Spring Framework 4.3.7.RELEASE(Spring Boot 1.5.2.RELEASE)
>systeminfo OS 名: Microsoft Windows 10 Pro OS バージョン: 10.0.14393 N/A ビルド 14393 OS ビルドの種類: Multiprocessor Free システムの種類: x64-based PC プロセッサ: 1 プロセッサインストール済みです。 [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~1596 Mhz >java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
APIとしてJSONを返してみる
まず、APIとして直近のメッセージをJSONとして返すエンドポイントを作ってみる。 以下のコードは、「Spring Bootで簡単なWebアプリケーションを書いてみる」で作ったアプリケーションをベースとする。
JSONを返すエンドポイントを作るには、Controllerに次のようなメソッドを追加する。
package com.example; (snip) import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MessageController { @Autowired private MessageService service; (snip) @RequestMapping("/messages.json") @ResponseBody public List<Message> messagesJson() { List<Message> messages = service.getRecentMessages(100); return messages; } }
@RequestMapping
はGET、POSTを問わないエンドポイントを表す。
メソッドに@ResponseBody
をつけJavaオブジェクトを返すようにすると、返り値がJacksonライブラリにより自動的にJSONに変換されて返される。
アプリケーションを起動した後適当なメッセージを投稿し、http://localhost:8080/messages.json にアクセスすると次のようになる。
$ curl -v http://localhost:8080/messages.json (snip) > GET /messages.json HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.49.1 > Accept: */* > (snip) < HTTP/1.1 200 < Content-Type: application/json;charset=UTF-8 < Transfer-Encoding: chunked < Date: Thu, 06 Apr 2017 13:49:22 GMT < (snip) [{"id":3,"name":"name3","text":"text3","remoteAddr":"0:0:0:0:0:0:0:1","createdAt":1491486551864},{"id":2,"name":"name2","text":"text2","remoteAddr":"0:0:0:0:0:0:0:1","createdAt":1491486548343},{"id":1,"name":"name1","text":"text1","remoteAddr":"0:0:0:0:0:0:0:1","createdAt":1491486544112}]
テーブルの内容がJSONで返ってきていることが確認できる。
Excelファイルとしてダウンロードできるようにしてみる
業務アプリケーションでは、データベースの内容をExcelファイルとしてエクスポートする機能が求められる場合がある。 Spring Frameworkでは、Apache POIというライブラリを使うことでExcelファイルを返すViewを作ることができる。 ここでは、直近のメッセージをxlsx形式でダウンロードする機能を作ってみる。
Apache POIは標準では付属しないので、まずプロジェクトにライブラリを追加する必要がある。 保存するファイル形式がxls形式の場合はpoiライブラリ、xlsx形式の場合はpoi-ooxmlライブラリが必要となる。
STSでは、標準でプロジェクトマネージャとしてMavenを使いライブラリを管理している。 ここで、MavenのCentral Repositoryを検索すると、poi-ooxmlの最新stable版が3.15であることがわかる。
プロジェクトにpoi-ooxml 3.15を追加するには次のようにする。
- 「demo [boot]」を右クリックして、「Maven」→「Add Dependency」を選択
- ダイアログの各フィールドに以下の文字列を入力してOK
- GroupId: org.apache.poi
- ArtifactId: poi-ooxml
- Version: 3.15
これにより、poi-ooxmlが依存する各種ライブラリも合わせて追加される。
Excelファイルを返すエンドポイントを作るには、Controllerに次のようなメソッドを追加する。
package com.example; (snip) import org.springframework.web.servlet.ModelAndView; @Controller public class MessageController { @Autowired private MessageService service; (snip) @RequestMapping("/messages.xlsx") public ModelAndView messagesXlsx() { List<Message> messages = service.getRecentMessages(100); return new ModelAndView(new MessagesXlsxView(), "messages", messages); } }
Excelファイルを構築するViewは次のようになる。
package com.example; import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.springframework.web.servlet.view.document.AbstractXlsxView; public class MessagesXlsxView extends AbstractXlsxView { @Override protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { @SuppressWarnings("unchecked") List<Message> messages = (List<Message>) model.get("messages"); Sheet sheet = workbook.createSheet("Recent messages"); // create header Row row = sheet.createRow(0); row.createCell(0).setCellValue("ID"); row.createCell(1).setCellValue("Name"); row.createCell(2).setCellValue("Text"); row.createCell(3).setCellValue("RemoteAddr"); row.createCell(4).setCellValue("CreatedAt"); // create body SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (int i=0; i<messages.size(); i++) { Message message = messages.get(i); row = sheet.createRow(i+1); row.createCell(0).setCellValue(message.getId()); row.createCell(1).setCellValue(message.getName()); row.createCell(2).setCellValue(message.getText()); row.createCell(3).setCellValue(message.getRemoteAddr()); row.createCell(4).setCellValue(dateFormatter.format(message.getCreatedAt())); } // enable auto filter sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, 4)); // adjust column width for (int i=0; i<5; i++) { sheet.autoSizeColumn(i); } } }
xlsx形式の場合はAbstractXlsxView、xls形式の場合はAbstractXlsViewを継承する。
アプリケーションを起動した後適当なメッセージを投稿し、http://localhost:8080/messages.xlsx にアクセスすると次のようになる。
$ curl -I http://localhost:8080/messages.xlsx HTTP/1.1 200 Pragma: private Cache-Control: private, must-revalidate Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet Content-Language: ja-JP Content-Length: 3711 Date: Thu, 06 Apr 2017 13:49:29 GMT
3713バイトのapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
が返っていることがわかる。
また、ブラウザでアクセスすると、構築したExcelファイルがダウンロードできることが確認できる。
PDFファイルの構築とダウンロード
Springでは、AbstractPdfViewとitextライブラリを使うことで、PDFファイルを構築して返すことも可能である。 全体の流れはExcelファイルの場合と同様であるため、ここでは省略する。