「Java/Tomcat/サーブレットからCSVファイルをダウンロードするサンプル(日本語ファイル名)」の編集履歴(バックアップ)一覧はこちら

Java/Tomcat/サーブレットからCSVファイルをダウンロードするサンプル(日本語ファイル名)」(2013/07/30 (火) 23:57:44) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

* サーブレットからCSVファイルをダウンロードするサンプル(日本語ファイル名) [[前回>Java/Tomcat/サーブレットからCSVファイルをダウンロードするサンプル]]作った、CSVファイルのダウンロードサンプルでしたが、このままでは日本語ファイル名を扱えないのが分かったので、日本語ファイル名にも対応出来るサーブレットのサンプルを作成しました。 * ■目次 #contents(fromhere=true) * ファイルの配置 /CONTEXT_ROOT ┣ WEB-INF ┃┣ src ┃┃┗ DynamicCsvJpServlet.java ┃┗ web.xml ┗ jsp  ┗ dynamic_csv_jp.jsp * 日本語対応サンプルサーブレット(DynamicCsvJpServlet.java) #highlight(){{ import java.io.*; import java.net.URLEncoder; import javax.servlet.*; import javax.servlet.http.*; import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility; public class DynamicCsvJpServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // POSTメソッドでアクセスが来てもGETメソッドで全部処理します。 doGet(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // CSV出力用データ String[][] rows = { { "0", "ダイナミック", "dynamic@example.com" }, { "1", "ホゲ", "hoge@example.com" }, { "2", "モゲ", "moge@example.com" }, { "3", "マゲ", "mage@example.com" }, { "4", "フゥ", "foo@example.com" }, { "5", "バァ", "bar@example.com" }, { "6", "グゥ", "goo@example.com" } }; // ファイル名設定 // リクエストパスからファイル名を取得 String fileName = new String(req.getPathInfo().substring(1).getBytes("ISO-8859-1"), "UTF-8"); // リクエストヘッダからユーザーエージェント(ブラウザの名前)取得 String ua = req.getHeader("user-agent"); if (ua.contains("MSIE")) { // IE用ファイル名エンコード fileName = URLEncoder.encode(fileName, "UTF-8"); } else { // IE以外(FireFox,Safari,Chrome)ファイル名エンコード fileName = MimeUtility.encodeWord(fileName, "ISO-2022-JP", "B"); } // レスポンスヘッダー設定 if (ua.contains("Safari")) { // サファリ用 resp.setContentType("application/octet-stream;"); } else { // サファリ以外用 resp.setContentType("text/csv; charset=UTF-8;"); resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } // CSVデータ作成 StringBuffer sb = new StringBuffer(); for (String[] row : rows) { for (int i = 0; i < row.length; i++) { if (i == 0) { sb.append("\""); } else { sb.append("\",\""); } sb.append(row[i]); if (i == row.length - 1) { sb.append("\"\n"); } } } // レスポンスにCSV出力 PrintWriter w = resp.getWriter(); w.print(sb.toString()); w.flush(); } } }} - 前回作ったCSV出力サーブレットを、日本語ファイル名に対応出来る用に修正しました。 - 修正箇所説明 #highlight(){{ // リクエストパスからファイル名を取得 String fileName = new String(req.getPathInfo().substring(1).getBytes("ISO-8859-1"), "UTF-8");}} - まずここで、リクエストパスからファイル名を取得します。 -- 例:「/hogeservlet/hoge.csv」にアクセス → リクエストパスに「/hoge.csv」が入る → 1文字目をカットして「hoge.csv」を取得 - リクエストパスに日本語が入ると文字化けしてしまうので、文字化け対策として一度バイト配列に戻し、UTF-8で文字列に戻しています。 #highlight(){{ // リクエストヘッダからユーザーエージェント(ブラウザの名前)取得 String ua = req.getHeader("user-agent"); if (ua.contains("MSIE")) { // IE用ファイル名エンコード fileName = URLEncoder.encode(fileName, "UTF-8"); } else { // IE以外(FireFox,Safari,Chrome)ファイル名エンコード fileName = MimeUtility.encodeWord(fileName, "ISO-2022-JP", "B"); } }} - ここでは、ブラウザ毎の動作の違いを吸収します。 - IEは日本語ファイル名は「URLEncoder.encode」を使いエンコードして上げる必要があります。 - FireFox Chromeは「MimeUtility.encodeWord」を使います。 #highlight(){{ // レスポンスヘッダー設定 if (ua.contains("Safari")) { // サファリ用 resp.setContentType("application/octet-stream;"); } else { // サファリ以外用 resp.setContentType("text/csv; charset=UTF-8;"); resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } }} - ここでもブラウザ毎の動作の違いを吸収しています。 - まず、サファリでは日本語のファイル名を「Content-Disposition」で上手く設定出来ませんでした。 -- そこでサファリ用に、リクエストパスにファイル名を持たせて、サファリの場合はコンテンツタイプを「application/octet-stream」するという方法にしました。 -- この対応でなんとか、ウィンドウズ7のサファリですが日本語のファイル名でダウンロードできるようになりました。 - サファリ以外は、前回とほぼ変わらずIE用とそれ以外用にエンコードしたファイル名を設定しています。 * web.xmlの設定 #highlight(){{ <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- サーブレットの宣言 --> <servlet> <servlet-name>dynamiccsvjpservlet</servlet-name> <servlet-class>DynamicCsvJpServlet</servlet-class> </servlet> <!-- サーブレットとurlのマッピング --> <servlet-mapping> <servlet-name>dynamiccsvjpservlet</servlet-name> <url-pattern>/dynamiccsvjpservlet/*</url-pattern> </servlet-mapping> </web-app> }} - サーブレットの宣言とURLのマッピングです。 - 「url-pattern」にワイルドカードを設定して、「/dynamiccsvjpservlet/日本語.csv」のようにアクセスすると、「DynamicCsvJpServlet」が実行され、*の部分に相当する「/日本語.csv」をサーブレットで取得出来るのです。 - この時点で、Tomcatを起動して「http://localhost:8080/CONTEXT_ROOT/dynamiccsvjpservlet/日本語.csv」にアクセスすると、CSVファイルのダウンロードダイアログが出てくると思います。 * サンプルサーブレットへのリンクを表示するJSP(dynamic_csv_jp.jsp) #highlight(){{ <%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <a href='<%=request.getContextPath()+"/dynamiccsvjpservlet/" + java.net.URLEncoder.encode("日本語.csv","UTF-8")%>'>エンコードあり</a><br> <a href='<%=request.getContextPath()+"/dynamiccsvjpservlet/日本語.csv"%>'>エンコードなし</a><br> </body> </html> }} - 日本語対応のサーブレットにアクセスするリンクを表示するJSPです。サーブレットのパスに続けてCSVのファイル名もURLに含めてあります。 - URLエンコードありとなし両方用意してありますが、どちらでも問題なくアクセス出来ます。 - アクセス出来ないブラウザがないとも限らないので、エンコードしておいたほうがよいと思いますが。 #highlight(){{ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <a href='/Tomcat7Test/dynamiccsvjpservlet/%E6%97%A5%E6%9C%AC%E8%AA%9E.csv'>エンコードあり</a><br> <a href='/Tomcat7Test/dynamiccsvjpservlet/日本語.csv'>エンコードなし</a><br> </body> </html> }} - JSPが出力したHTMLです。 - ファイル名エンコードのありとなしがはっきり分かりますが、どちらでも問題なくアクセス出来ました。 * ブラウザでアクセス 「http://localhost:8080/CONTEXT_ROOT/jsp/dynamic_csv_jp.jsp」にアクセスすると、ダウンロードのリンクが表示されて、リンククリックでブラウザのダウンロード処理が動きます。 * 他のTomcatサンプルはこちら #inc(Java/Tomcat/サンプル) * コメント #pcomment(reply)
[[前回>Java/Tomcat/サーブレットからCSVファイルをダウンロードするサンプル]]作った、CSVファイルのダウンロードサンプルでしたが、このままでは日本語ファイル名を扱えないのが分かったので、日本語ファイル名にも対応出来るサーブレットのサンプルを作成しました。 * ■目次 #contents(fromhere=true) * ファイルの配置 /CONTEXT_ROOT ┣ WEB-INF ┃┣ src ┃┃┗ DynamicCsvJpServlet.java ┃┗ web.xml ┗ jsp  ┗ dynamic_csv_jp.jsp * 日本語対応サンプルサーブレット(DynamicCsvJpServlet.java) #highlight(){{ import java.io.*; import java.net.URLEncoder; import javax.servlet.*; import javax.servlet.http.*; import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility; public class DynamicCsvJpServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // POSTメソッドでアクセスが来てもGETメソッドで全部処理します。 doGet(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // CSV出力用データ String[][] rows = { { "0", "ダイナミック", "dynamic@example.com" }, { "1", "ホゲ", "hoge@example.com" }, { "2", "モゲ", "moge@example.com" }, { "3", "マゲ", "mage@example.com" }, { "4", "フゥ", "foo@example.com" }, { "5", "バァ", "bar@example.com" }, { "6", "グゥ", "goo@example.com" } }; // ファイル名設定 // リクエストパスからファイル名を取得 String fileName = new String(req.getPathInfo().substring(1).getBytes("ISO-8859-1"), "UTF-8"); // リクエストヘッダからユーザーエージェント(ブラウザの名前)取得 String ua = req.getHeader("user-agent"); if (ua.contains("MSIE")) { // IE用ファイル名エンコード fileName = URLEncoder.encode(fileName, "UTF-8"); } else { // IE以外(FireFox,Safari,Chrome)ファイル名エンコード fileName = MimeUtility.encodeWord(fileName, "ISO-2022-JP", "B"); } // レスポンスヘッダー設定 if (ua.contains("Safari")) { // サファリ用 resp.setContentType("application/octet-stream;"); } else { // サファリ以外用 resp.setContentType("text/csv; charset=UTF-8;"); resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } // CSVデータ作成 StringBuffer sb = new StringBuffer(); for (String[] row : rows) { for (int i = 0; i < row.length; i++) { if (i == 0) { sb.append("\""); } else { sb.append("\",\""); } sb.append(row[i]); if (i == row.length - 1) { sb.append("\"\n"); } } } // レスポンスにCSV出力 PrintWriter w = resp.getWriter(); w.print(sb.toString()); w.flush(); } } }} - 前回作ったCSV出力サーブレットを、日本語ファイル名に対応出来る用に修正しました。 - 修正箇所説明 #highlight(){{ // リクエストパスからファイル名を取得 String fileName = new String(req.getPathInfo().substring(1).getBytes("ISO-8859-1"), "UTF-8");}} - まずここで、リクエストパスからファイル名を取得します。 -- 例:「/hogeservlet/hoge.csv」にアクセス → リクエストパスに「/hoge.csv」が入る → 1文字目をカットして「hoge.csv」を取得 - リクエストパスに日本語が入ると文字化けしてしまうので、文字化け対策として一度バイト配列に戻し、UTF-8で文字列に戻しています。 #highlight(){{ // リクエストヘッダからユーザーエージェント(ブラウザの名前)取得 String ua = req.getHeader("user-agent"); if (ua.contains("MSIE")) { // IE用ファイル名エンコード fileName = URLEncoder.encode(fileName, "UTF-8"); } else { // IE以外(FireFox,Safari,Chrome)ファイル名エンコード fileName = MimeUtility.encodeWord(fileName, "ISO-2022-JP", "B"); } }} - ここでは、ブラウザ毎の動作の違いを吸収します。 - IEは日本語ファイル名は「URLEncoder.encode」を使いエンコードして上げる必要があります。 - FireFox Chromeは「MimeUtility.encodeWord」を使います。 #highlight(){{ // レスポンスヘッダー設定 if (ua.contains("Safari")) { // サファリ用 resp.setContentType("application/octet-stream;"); } else { // サファリ以外用 resp.setContentType("text/csv; charset=UTF-8;"); resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } }} - ここでもブラウザ毎の動作の違いを吸収しています。 - まず、サファリでは日本語のファイル名を「Content-Disposition」で上手く設定出来ませんでした。 -- そこでサファリ用に、リクエストパスにファイル名を持たせて、サファリの場合はコンテンツタイプを「application/octet-stream」するという方法にしました。 -- この対応でなんとか、ウィンドウズ7のサファリですが日本語のファイル名でダウンロードできるようになりました。 - サファリ以外は、前回とほぼ変わらずIE用とそれ以外用にエンコードしたファイル名を設定しています。 * web.xmlの設定 #highlight(){{ <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- サーブレットの宣言 --> <servlet> <servlet-name>dynamiccsvjpservlet</servlet-name> <servlet-class>DynamicCsvJpServlet</servlet-class> </servlet> <!-- サーブレットとurlのマッピング --> <servlet-mapping> <servlet-name>dynamiccsvjpservlet</servlet-name> <url-pattern>/dynamiccsvjpservlet/*</url-pattern> </servlet-mapping> </web-app> }} - サーブレットの宣言とURLのマッピングです。 - 「url-pattern」にワイルドカードを設定して、「/dynamiccsvjpservlet/日本語.csv」のようにアクセスすると、「DynamicCsvJpServlet」が実行され、*の部分に相当する「/日本語.csv」をサーブレットで取得出来るのです。 - この時点で、Tomcatを起動して「http://localhost:8080/CONTEXT_ROOT/dynamiccsvjpservlet/日本語.csv」にアクセスすると、CSVファイルのダウンロードダイアログが出てくると思います。 * サンプルサーブレットへのリンクを表示するJSP(dynamic_csv_jp.jsp) #highlight(){{ <%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <a href='<%=request.getContextPath()+"/dynamiccsvjpservlet/" + java.net.URLEncoder.encode("日本語.csv","UTF-8")%>'>エンコードあり</a><br> <a href='<%=request.getContextPath()+"/dynamiccsvjpservlet/日本語.csv"%>'>エンコードなし</a><br> </body> </html> }} - 日本語対応のサーブレットにアクセスするリンクを表示するJSPです。サーブレットのパスに続けてCSVのファイル名もURLに含めてあります。 - URLエンコードありとなし両方用意してありますが、どちらでも問題なくアクセス出来ます。 - アクセス出来ないブラウザがないとも限らないので、エンコードしておいたほうがよいと思いますが。 #highlight(){{ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <a href='/Tomcat7Test/dynamiccsvjpservlet/%E6%97%A5%E6%9C%AC%E8%AA%9E.csv'>エンコードあり</a><br> <a href='/Tomcat7Test/dynamiccsvjpservlet/日本語.csv'>エンコードなし</a><br> </body> </html> }} - JSPが出力したHTMLです。 - ファイル名エンコードのありとなしがはっきり分かりますが、どちらでも問題なくアクセス出来ました。 * ブラウザでアクセス 「http://localhost:8080/CONTEXT_ROOT/jsp/dynamic_csv_jp.jsp」にアクセスすると、ダウンロードのリンクが表示されて、リンククリックでブラウザのダウンロード処理が動きます。 * 他のTomcatサンプルはこちら #inc(Java/Tomcat/サンプル) * コメント #pcomment(reply)

表示オプション

横に並べて表示:
変化行の前後のみ表示: