Magnolia Tech

いつもコードのことばかり考えている人のために。

ファイル名からMIME Typeを教えてくれるJavaのライブラリ

ScalatraのMIME Type関係の機能が盛大に壊れている訳ですが、じゃあそれを直すためにMIME Typeを教えてくれるライブラリについて調べてみました。標準ライブラリだけでもいくつか方法が有りますね。

Files.probeContentType

Java7から導入されたFiles.probeContentTypeを使うと、簡単にMIME Typeを取得できます。

scala> import java.nio.file.Files
import java.nio.file.Files

scala> import java.nio.file.Paths
import java.nio.file.Paths

scala> val htmlfile = Paths.get("test.html")
htmlfile: java.nio.file.Path = test.html

scala> Files.probeContentType(htmlfile)
res2: String = text/html

scala> val cssfile = Paths.get("test.css")
cssfile: java.nio.file.Path = test.css

scala> Files.probeContentType(cssfile)
res3: String = text/css

scala> val jsfile = Paths.get("test.js")
jsfile: java.nio.file.Path = test.js

scala> Files.probeContentType(jsfile)
res4: String = text/javascript

最後、javascripttext/javascriptになっていますが、application/javascriptで返して欲しいですね。カスタマイズは可能です。下記のブログエントリが参考になります。

waman.hatenablog.com

返って来る値が実装依存なので、自分が使いたいMIME Typeはきちっとテストを書いておきましょう。

URLConnection.guessContentTypeFromName

URLConnection.guessContentTypeFromNameもファイル名からMIME Typeを取得できます。

scala> import java.net.URLConnection
import java.net.URLConnection

scala> URLConnection.guessContentTypeFromName("test.html")
res5: String = text/html

scala> URLConnection.guessContentTypeFromName("test.css")
res6: String = null

scala> URLConnection.guessContentTypeFromName("test.js")
res7: String = null

デフォルトでは、かなり残念な結果になりました。こちらもMIME Typeはカスタマイズ可能です。こちらの記事によると、content-types.propertiesというファイルを用意すれば良さそうです。

Getting and Extending mime-types in Javathilosdevblog.wordpress.com

content-types.propertiesの正式なフォーマットの解説が見つけられませんでしたが、こちらのブログにサンプルファイルが紹介されていました。

alvinalexander.com

javax.activation.MimetypesFileTypeMap

最後はjavax.activation.MimetypesFileTypeMapです。

scala> import javax.activation.MimetypesFileTypeMap
import javax.activation.MimetypesFileTypeMap

scala> val mimeTypesMap = new MimetypesFileTypeMap
mimeTypesMap: javax.activation.MimetypesFileTypeMap = javax.activation.MimetypesFileTypeMap@7e258a05

scala> mimeTypesMap.getContentType("test.html")
res8: String = text/html

scala> mimeTypesMap.getContentType("test.css")
res9: String = application/octet-stream

scala> mimeTypesMap.getContentType("test.js")
res10: String = application/octet-stream

こちらもcssjavascriptが正しく扱えていません。カスタマイズ方法は公式ドキュメントにきちんと書かれています。

MimetypesFileTypeMap (Java Platform SE 8)

しかし、残念ながらこのパッケージは将来廃止が予定されています。

JEP 320: Remove the Java EE and CORBA Modules

これから新しく使うには相応しくないですね。

おわりに

ファイル名からMIME Typeを取得する方法を紹介しました。標準ライブラリだけでも3種類有って、更にそれぞれカスタマイズ方法が違うってなかなかカオスな感じですね。

ScalatraのMimeTypesは、ファイルの内容に基づいてMIME Typeを推測する機能も有るので、次回はその方法について紹介します。

スッキリわかるJava入門 第2版 (スッキリシリーズ)

スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ)

スッキリわかる サーブレット&JSP入門 (スッキリシリーズ)