プロが教えるわが家の防犯対策術!

こんにちは、GAE勉強中の者です。
現在ローカルの画像をFlickrへアップロードしようと試行錯誤しています。

http://d.hatena.ne.jp/sotarok/20081218を参考に
認証やトークンの取得までできましたが、肝心のファイルアップロードではまっています。

app engineのクラスで「HTTPRequest」というのがあるのですが、
ドキュメントを見てもファイルを指定できないみたいでよく分かりませんでした。

フリッカーのサイト(以下)でサンプルが示されているのですが、
どうやってPOSTする情報を構築したらよいかが分かりません。
http://www.flickr.com/services/api/upload.exampl …

どんな些細なことでご意見いただけたら幸いです。
よろしくお願いします。

A 回答 (3件)

どうやら仕様のようですね。



http://code.google.com/appengine/kb/java.html#wr …

Why can't I read from this file?
It is possible to read from a file which is uploaded as part of your application provided that it is in the following locations:
war/WEB-INF
in a location matching the <resource-files> pattern in appengine-web.xml (which by default includes everything)
If the file location is not the issue, the problem may be that the method you are using to read from the file is not whitelisted. Your application can use any IO classes that are useful for reading from the file system, such as File, FileInputStream, FileReader, or RandomAccessFile. For a full list of whitelisted classes, please see the JRE Class White List.
If you need to get file access to your own resources (such as properties files), you could put these files inside of jars and use Class or ClassLoader to load them.

あらかじめパッケージに入れてないと読めないみたいです。

とりあえずこちらにアップロードする技がのっていました。
http://shogi-software.blogspot.com/2009/04/googl …

とりあえずテストする目的なら、jarにまとめてしまって、クラスローダを使って読むのが一番早いんじゃないかと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。
参考にさせていただきます。

お礼日時:2009/06/10 05:49

早速いっこ書きまちがいみつけました(^^;)すみません



long totalContentLength = metaDataBytes.length + imgDataBytes.length + endOfDataBytes;は
long totalContentLength = metaDataBytes.length + imgDataBytes.length + endOfDataBytes.length;
ですね。。。
    • good
    • 0

なかなかお答えがないようなので、正直自分もまだ最近少し勉強し始めただけなのですが、書いてみました。

とかいってテストしてないですが。。。(exceptionハンドリングとかエラーチェックとか、ストリームのクローズとかは省略しています)

多分やり方自体若干微妙ですが、一応動くことは動くんじゃないかと思います(テキトーですみません)

      private static final String br = "\r\n";

          //ファイル以外の準備
          String boundary = "-----------------------------7d44e178b0434";
          String conDip = "Content-Disposition: form-data; "

 

String api_key = boundary + br + conDip + "name=\"api_key\"" + br
                   + br
                    + /*api_key*/ + br;
String auth_token = boundary + br + conDip + "name=\"auth_token\"" + br
                   + br
                    + /*auth_token*/ + br;

String api_sig = boundary + br + conDip + "name=\"api_sig\"" + br
                   + br
                    + /*api_sig*/ + br;
          String imgMetaInfo = boundary + br + conDip + "name=\"aaa\""; filename=\"c:\\test.jpg\" + br
                      +br
                      +"Content-Type: image/jpeg" + br
                      +br;

          String metaData = api_key + auth_token + api_sig + imgMetaInfo;

          //ファイルの準備          
File file = new File("c:\\test.jpg");
          InputStream is = new BufferedInputStream(new FileInputStream(file));
          byte[] bytes = new byte[(int)file.length()];
          InputStream is = new FileInputStream(file);
          int offset = 0;
          int numRead = 0;
        while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
             offset += numRead;
        }


          //コンテンツの準備
          String endOfData = br + "-----------------------------7d44e178b0434--" + br;
          byte[] metaDataBytes = metaData.getBytes();
          byte[] imgDataBytes = bytes;
          byte[] endOfDataBytes = endOfData.getBytes();
          long totalContentLength = metaDataBytes.length + imgDataBytes.length + endOfDataBytes;

                    
          
          //コネクションの準備
          HttpURLConnection connection = null;
          URL serverAddress = null;
    
          serverAddress = new URL("http://api.flickr.com/services/upload/");
          connection = null;
          connection = (HttpURLConnection)serverAddress.openConnection();
          connection.setRequestMethod("POST");
          connection.setDoOutput(true);
          connection.setReadTimeout(10000);
          String cType = "multipart/form-data; boundary=---------------------------7d44e178b0434";
connection.setRequestProperty("Content-type", cType);
          con.setRequestProperty("Content-Length", "" + totalContentLength);
          //送信
          connection.connect();
          
          out = new BufferedOutputStream(connection.getOutputStream());
          out.write(metaDataBytes);
          out.write(imgDataBytes);
          out.write(endOfDataBytes);
          out.flush();

//クローズとか

この回答への補足

ご回答ありがとうございます。とても感謝いたします。

早速やってみたのですが、いくつか質問があります。
書き間違えだと思うのですが、「//ファイルの準備」のところでBufferedInputStreamとFileInputStreamを「InputStream is」に入れている点と
FileIO辺りで例外が発生します。

例えば
File file = new File("c:\\test.jpg");
int len = (int)file.length();
で実行すると、2行目で例外が発生してしまいます。

コンソールには以下のように出力されていました。
java.security.AccessControlException: access denied (java.io.FilePermission c:\test.jpg read)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:122)
at java.lang.SecurityManager.checkRead(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.daisukeyamashita.test.urlfetch.server.GreetingServiceImpl.uploadPicture(GreetingServiceImpl.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:54)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:306)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:313)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

すいません、なにか分かりますでしょうか。
よろしくお願いします。

補足日時:2009/06/08 06:27
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!