本次任務:上傳安卓客戶端的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"); } }