1

私はApacheMyFacesTomahawkを利用して、JSFプロジェクトでファイルのアップロードを利用しました。アップロードされたファイルを正常に取得できましたが、特にzipファイルの場合、ファイルタイプを識別しようとするたびに、getContentType()関数は常にを返しapplication/octet-streamます。どうしてこんなことに?

私はそれが私の設定エラーであると思いますweb.xml、以下はファイルです:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

    <display-name>Project 1</display-name>

    <context-param>
        <param-name>facelets.LIBRARIES</param-name>
        <param-value>/WEB-INF/el-taglib.xml</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name>
        <param-value>true</param-value>
    </context-param>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>

    <mime-mapping>
        <extension>zip</extension>
        <mime-type>application/zip</mime-type>
    </mime-mapping>

</web-app>

誰かが私に手を貸してくれませんか?

4

1 に答える 1

3

Tomahawk のUploadedFile#getContentType()メソッドの結果は、MIME マッピングに基づいてサーバーによって設定されるのではなく、サーバーに送信する前web.xmlにクライアント自体によって直接multipart/form-dataヘッダーに設定されます。したがって、リクエストボディから抽出されるだけです。

期待または希望する値が返されない場合は、アップロードされたファイルのファイル拡張子に基づいて、いつでも MIME タイプを確認できますExternalContext#getMimeType()

String contentType = externalContext.getMimeType(uploadedFile.getName());

ただし、ファイル拡張子はクライアントによって偽造される可能性があることに注意してください (multipart/form-dataヘッダーのコンテンツ タイプである可能性があります!)。そのため、拡張子 (および取得/決定されたコンテンツ タイプ!) に基づく検出は必ずしも十分に堅牢ではありません。たとえば、クライアントの名前が変更されfoo.exeた可能性がありますfoo.zip。ファイルが本当に ZIP ファイルであるかどうかを判断する最善の方法は、ファイルを ZIP ファイルとして開き、スローされた例外をキャッチすることです。標準の Java SE API は、ZipFileこのためのコンストラクターを提供します。

FilenameUtilsアップロードされたファイルを次のように保存していると仮定します ( IOUtilsApache Commons IO からのものであり、Tomahawk の必要な依存関係の 1 つであるため、既に持っているはずです):

String prefix = FilenameUtils.getBaseName(uploadedFile.getName()); 
String suffix = FilenameUtils.getExtension(uploadedFile.getName());
File uploadLocation = new File("/path/to/uploads"); // Make it configureable!
File file = File.createTempFile(prefix + "-", "." + suffix, uploadLocation);

InputStream input = uploadedFile.getInputStream();
OutputStream output = new FileOutputStream(file);

try {
    IOUtils.copy(input, output);
} finally {
    IOUtils.closeQuietly(output);
    IOUtils.closeQuietly(input);
}

次に、それが有効な ZIP ファイルであるかどうかを次のように判断できるはずです。

try {
    new ZipFile(file);
} catch (ZipException e) {
    // Here, we know that it's not a valid ZIP file!
}

以下も参照してください。

于 2012-12-07T18:18:08.293 に答える