FC2ブログ

スポンサーサイト

-------- --:--:-- --

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【Java】web.xmlでファイル拡張子とMIME-TYPEのマッピング【Servlet】

2011-06-21 01:06:09 Tue


Google App Engine for Javaを使っていると、Apacheのように設定はできないので、
任意の拡張子ファイルに任意のMIME-TYPEを書いてレスポンスすることができなくて困った。
次のようにweb.xmlに設定するとできるようです。

http://d.hatena.ne.jp/scalar/20101223/1293087549

マークアップすると次の通り。

<mime-mapping>
   <extension>manifest</extension>
   <mime-type>text/cache-manifest</mime-type>
</mime-mapping>


でもこの設定だとここで設定した拡張子 extension のファイルすべてに適用されてしまう。
レスポンスを犠牲にしても手動設定する場合は次のようにサーブレットを通すと良いみたいです。

※2011/06/21 01:04:13 上記、Google App Engine上で未検証です。

http://syamamot343.blog110.fc2.com/?no=351

Google App Engineの公式ドキュメント
http://code.google.com/intl/ja/appengine/docs/java/config/appconfig.html

1.appengine-web.xml
任意のMIME-TYPEを付加したいファイルは、GAE上で静的ファイルではなくリソースファイルとして定義
<resource-files>
	<include path="/**.ogg" />
	<include path="/**.ogv" />
	<include path="/**.mp4" />
	<include path="/**.webm" />
	<include path="/resouces/*.*" />
</resource-files>



2.web.xml
*.extensions のようにサーブレットでURLをサーブレットにマッピング
<!-- resource file response -->
<servlet>
<servlet-name>FileAddType</servlet-name>
    <servlet-class>info.isann.servlet.FileAddType</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FileAddType</servlet-name>
    <url-pattern>*.ogg</url-pattern>
    <url-pattern>*.ogv</url-pattern>
    <url-pattern>*.mp4</url-pattern>
    <url-pattern>*.webm</url-pattern>
</servlet-mapping>


3.サーブレット
2でマッピングしたサーブレットでヘッダにMIME-TYPEを書きこむ。
リクエストURLの末尾にある拡張子によってMIME-TYPEを分ける。
このサーブレットはimgタグとかから呼ばれてくるのでGETメソッドとして書いておく。
package info.isann;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FileAddType extends HttpServlet {

	private static final Logger logger = Logger.getLogger(DevelopmentReadServlet.class.getName());

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException {
		
		// target file
		String targetpath = req.getRequestURI();
		logger.fine("request uri is : " + targetpath);
		int start = targetpath.lastIndexOf("/") + 1;
		int last  = targetpath.length();
		targetpath = "/resouces/" + targetpath.substring(start, last);
		logger.fine("target path is ... : " + targetpath);

		// resource file
		InputStream is = null;

		try{
			is = this.getServletContext().getResourceAsStream(targetpath);

			// check: is file avalable?
			if (is == null) {
				// not exist				resp.setContentType("text/plain");
				resp.getWriter().println("File not found...");
			} else {
				// file exist
				int filesize = is.available();

				// set response header
				setResponseHeader(resp, targetpath, filesize);

				// output
				OutputStream out = resp.getOutputStream();
				byte[] byteBuf = new byte[8192];
				for (;;) {
					int iRead = is.read(byteBuf, 0, byteBuf.length);
					if (iRead < 0) {
						break;
					}
					out.write(byteBuf, 0, iRead);
				}
			}
		} finally{
			if(is != null){
				is.close();
			}
		}
	}

	private void setResponseHeader(final HttpServletResponse response,
            String filename, final int fileLength) {
        if (filename.endsWith(".pdf")) {
            // PDF
            response.setContentType("application/pdf");
        } else if (filename.endsWith(".xls")) {
            // Excel
            response.setContentType("application/vnd.ms-excel");
        } else if (filename.endsWith(".xml")) {
            // XML
            response.setContentType("text/xml");
        } else if (filename.endsWith(".jad")) {
            // JAD
            response.setContentType("text/vnd.sun.j2me.app-descriptor");
        } else if (filename.endsWith(".cod")) {
            // COD
            response.setContentType("application/vnd.rim.cod");
        } else if (filename.endsWith(".ogg")) {
            // OGG
            response.setContentType("video/ogg");
        } else if (filename.endsWith(".ogv")) {
            // OGV
            response.setContentType("video/ogg");
        } else if (filename.endsWith(".mp4")) {
            // MP4
            response.setContentType("video/mp4");
        } else if (filename.endsWith(".webm")) {
            // WEBM
            response.setContentType("video/webm");
        } else {
            // other is binary
            response.setContentType("application/octet-stream");
        }

        if (fileLength > 0) {
            // Length
            response.setContentLength(fileLength);
        }

        // Disable cache
        response.addHeader("Cache-Control", "no-cache");
        response.addHeader("Pragma", "no-cache");
        response.addHeader("Expires", "0");
    }

}


なお、使う側(クライアントに表示させるHTMLとか)は次の通りサーブレットを意識することなく普通にアクセスする。


<video id="video" controls>
  <source src="/reosuces/sample2.ogv" type="video/ogg">
  <source src="/reosuces/sample2.mp4" type="video/mp4">
  <source src="/reosuces/sample2.webm" type="video/webm">
</video>



また、Pythonではapp.yamlで設定できるみたいです。

http://himaxoff.blog111.fc2.com/blog-entry-135.html


- url: /sound/(.+\.ogg)
  static_files: sound/\1
  upload: sound/(.+\.ogg)
  mime_type: audio/ogg
- url: /sound/(.+\.mp3)
  static_files: sound/\1
  upload: sound/(.+\.mp3)
  mime_type: audio/mpeg

スポンサーサイト

⇒comment

Secret

名言集
全記事(数)表示
全タイトルを表示
ブログ内検索
Loading
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。