android網絡上傳圖片數據到服務端

       本次任務:上傳安卓客戶端的res下的一張圖片到服務器端的E盤下。java

        本身搗鼓這個做品時也真的費了勁,遇到三個小麻煩搞了兩天才搞好。我愈來愈以爲能有個前輩在身邊及時進行輔導能省下不少時間,可能這就是教師的兒女通常學習成績都不錯能上好大學的緣由吧,教師比較閒相對來講又不斷學習能給子女及時解答。android

    遇到的4個錯誤:apache

1:不知道怎麼獲取res下的某個圖片的輸入流?最後也是網絡試了好多個別人的方法,這個通了tomcat

  //圖片數據難點
               Resources r = HttpImageUpload.this.getBaseContext().getResources();
               //取得對應圖片的輸入流,圖片名字能夠和最終寫入的文件名不一致
               //圖片格式能夠是png也能夠是jpg
               InputStream is = r.openRawResource(R.drawable.w);服務器

2:一個錯誤:覺得out.flush();包含了發送數據的功能,結果並非,out.flush()只是清空掉暫時存儲在內存緩衝區的全部數據,鏈接返回一個輸入流纔是發送數據並返回相應的信息
              InputStream in=con.getInputStream();網絡

3.一個錯誤沒法解決:app

服務端報錯: Servlet.service() for servlet [android.HttpImageUpload] in context with path [/AndroidServer]threwexception[org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed streamdom

最後發現是請求頭Content-Type後面多加了冒號致使的。ide

4.在開發環境爲AndroidStudio中和Eclipse中如出一轍的代碼,結果始終沒法識別R.drawable.baby;工具

Error:Execution failed for task ':app:compileDebugJava'.
> Compilation failed; see the compiler error output for details.

網上說是開發工具的不一致致使的,在搞搞仍是沒用,最後用了

@SuppressWarnings("ALL")

錯誤就消失了,成功運行了,該批註是編譯器對某些警告進行忽略的做用。

下面附上代碼:

安卓客戶端

package internethttp;

import android.content.res.Resources;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
import com.internethttp.R;


public class HttpImageUpload extends Activity {
public Button tv_btn;
    public URL url;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image);
        tv_btn= (Button) findViewById(R.id.tv_btn);
        try {
            url=new URL("http://ly-and-tl.uicp.cn:42696/AndroidServer/HttpImageUpload");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        tv_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  new httpImgThread(url).start();
            }
        });
    }
   class httpImgThread extends Thread{
      URL URL;
       String prefix="--";//結尾要在分隔符後加這個
//分隔符其實能夠很隨意指定數字,多少位都行,但注意的是正文比請求頭的分隔符多出兩個中槓
       String boundary=UUID.randomUUID().toString();
       String end="\r\n";//換行
       httpImgThread(URL l){
         URL=l;
         System.out.println(boundary);
       }
       @Override
       public void run() {
           try {
//        	   第三種請求體的請求體被分紅爲多個部分,文件上傳時會被使用,
//        	   這種格式最早應該是被用於郵件傳輸中,每一個字段/文件都被boundary(Content-Type中指定)分紅單獨的段,
//        	   每段以-- 加 boundary開頭,而後是該段的描述頭,描述頭以後空一行接內容
               HttpURLConnection con=(HttpURLConnection)URL.openConnection();
               con.setRequestMethod("POST");
               con.setDoOutput(true);//容許輸出
               con.setDoInput(true);//容許輸入
               //數據類型表單的形式,分隔符指定
               con.setRequestProperty("Connection:", "keep-alive");
               //請求消息頭,以表單的形式發送數據到服務端,指定分隔符隔開不一樣的文件數據
               //muiltipart/form-data能夠以二進制方式上傳文件
               con.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
               DataOutputStream out=new DataOutputStream(con.getOutputStream());
               //分隔符換行,正文開始
               out.writeBytes(prefix+boundary+end);
               //指定鍵名,鍵值,name是控件的name,根據他後臺找出對應圖片,一個name標識一個文件
               //含有filename會被當成一個文件
               out.writeBytes("Content-Disposition:form-data;name=\"ooo\";"
+"fliename=\"upload.png\" " +end);
               out.writeBytes(end);
               //圖片數據難點
               Resources r = HttpImageUpload.this.getBaseContext().getResources();
               //取得對應圖片的輸入流,圖片名字能夠和最終寫入的文件名不一致
               //圖片格式能夠是png也能夠是jpg
               InputStream is = r.openRawResource(R.drawable.w);
               byte[] b=new byte[1024*4];
               int len=0;
               //讀取圖片數據
               while((len=is.read(b))!=-1){
            	   //is輸入流讀出來暫存到b中
                   out.write(b,0,len);
               //將b中的數據寫入out輸出流中,從0開始的len個字節
               }
               //換行
               out.writeBytes(end);
               //分隔符換行後面多加--
               out.writeBytes(prefix + boundary + prefix + end);
               //並不發送,是清空緩衝區殘存的的數據流
               out.flush();
               //下面纔是發送請求並拿到返回的輸入流
               InputStream in=con.getInputStream();
               if(out!=null)out.close();
               if(is!=null)is.close();
               if(in!=null) in.close();
               
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
}

服務器端:

package android;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

//servlet3.0後簡單的定義網址的方式
@WebServlet("/HttpImageUpload")
//指定文件上傳的位置
@MultipartConfig(location="e:\\")//大小寫均可以
public class HttpImageUpload extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//取出文件,根據前臺請求發送的文件名name
//servlet3.0後纔有的方法
		Part part=request.getPart("ooo");
//寫進文件名爲upload.png的文件中
    	part.write("upload.png");
		response.setCharacterEncoding("UTF-8");
	}

}
相關文章
相關標籤/搜索