1

JSP ファイルのアップロードと検証サーブレットを介して Blobstore に画像をアップロードしようとしています。JSP部分は次のとおりです。

<form action="/testuploadmimevalidation?provider-key=testprovider" method="post" enctype="multipart/form-data">
    <input type="text" name="foo">
    <input type="file" name="myfile" >
    <input type="submit" value="Submit">
</form>

Java クラスTestUploadMimeValidationは次のとおりです。

public class TestUploadMimeValidation extends HttpServlet {

    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
    private static final Logger log = Logger.getLogger(TestUploadMimeValidation.class.getName());
    private static final boolean PRODUCTION_MODE = SystemProperty.environment.value() == SystemProperty.Environment.Value.Production;
    private static final String URL_PREFIX = PRODUCTION_MODE ? "" : "http://127.0.0.1:8080";

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        InputStream in = req.getInputStream();
        int formDataLength = req.getContentLength();
        byte dataBytes[] = new byte[formDataLength];
        int len;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        while ((len = in.read(dataBytes, 0, formDataLength)) != -1)
            bos.write(dataBytes, 0, len);

        dataBytes = bos.toByteArray();
        String urlStr = URL_PREFIX + BlobstoreServiceFactory.getBlobstoreService().createUploadUrl("/testupload");
        URLFetchService urlFetch = URLFetchServiceFactory.getURLFetchService();
        HTTPRequest request = new HTTPRequest(new URL(urlStr), HTTPMethod.POST, FetchOptions.Builder.withDeadline(20.0));
        request.setHeader(new HTTPHeader("Content-Type", "multipart/form-data"));
        request.setPayload(dataBytes);

        System.out.println("step1");

        try {
            HTTPResponse response = urlFetch.fetch(request);
            System.out.println("step2");
        } catch (IOException e) {

        } catch (NullPointerException e) {

        }

        System.out.println("step3");
    }
}

このクラスは画像を Blobstore に問題なくアップロードしますが、NullPointerException. スタックトレースは次のとおりです。

WARNING: /_ah/upload/ag5tOGJ5dXMtZGV2ZWxvcHIbCxIVX19CbG9iVXBsb2FkU2Vzc2lvbl9fGAIM
java.lang.NullPointerException
        at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:143)
        at com.google.appengine.api.blobstore.dev.UploadBlobServlet.handleUpload(UploadBlobServlet.java:180)
        at com.google.appengine.api.blobstore.dev.UploadBlobServlet.access$000(UploadBlobServlet.java:72)
        at com.google.appengine.api.blobstore.dev.UploadBlobServlet$1.run(UploadBlobServlet.java:101)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.google.appengine.api.blobstore.dev.UploadBlobServlet.doPost(UploadBlobServlet.java:98)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
        at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:326)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
        at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

この NPE のため、TestUpload.javaクラス内の私のコードは実行されません。sはprintln問題なく出ます。「step3」と表示されます。画像はデータストアに保存されます。しかし、実行するコードを取得できませんTestUpload。何が例外を引き起こしているのか考えていますか? マルチパートをいじろうとしましたが、あまり成功しませんでした。

この問題に関するヘルプをいただければ幸いです。

4

3 に答える 3

4

私が使う

<form action="<%= blobstoreService.createUploadUrl("/catalog/actions/add") %>" method="post" enctype="multipart/form-data" >
于 2011-05-17T18:40:25.770 に答える
0

TL;DR: 従来のフォーム送信ルートの代わりに AJAX を使用してアップロードしようとしたときに、この特定の奇妙なエラーが発生した場合の解決策は、AJAX リクエストの作成時に「Content-Type」ヘッダーを設定しないことです。これを削除すると、それは私のために働き始めました。

詳細: どうやら、AJAX 要求の本文として FormData オブジェクトを渡すと、「Content-Type」ヘッダーに「multipart/form-data」が自動的に設定され、必要な境界文字列も設定されます (これは、自分で content-type を設定するだけです)。

追加情報: この境界文字列は、私の知る限り、ランダムに生成されたものであり、「Content-Type」ヘッダーを介して独自の境界を定義することはできません (試してみましたが、本文で使用される境界は依然としてランダムに生成された文字列であり、ヒープ スペース エラー)。AJAX 要求は、ランダムに生成された境界文字列をヘッダーに割り当てる必要があり、独自のコンテンツ タイプを設定すると、そのヘッダーが上書きされます。

私はここから手がかりを得ました: ajax の html フォーム enctype (ただし、jQuery 関連ですが、Content-type ヘッダーを設定するロジックはネイティブの webkit/browser ロジックです)

于 2015-11-24T04:43:41.120 に答える