最近在作上傳文件的服務,簡單看了網上的教程。結合實踐共享出代碼。web
因爲網上的大多數沒有服務端的代碼,這可不行呀,沒服務端怎麼調試呢。緩存
Ok,先上代碼。cookie
Android 上傳比較簡單,主要用到的是 HttpURLConnection 類,而後加一個進度條組件。app
private ProgressBar mPgBar; class UploadTask extends AsyncTask<Object,Integer,Void>{ private DataOutputStream outputStream = null; private String fileName; private String uri; private String mLineEnd = "\r\n"; private String mTwoHyphens = "--"; private String boundary = "*****"; File uploadFile ; long mTtotalSize ; // Get size of file, bytes public UploadTask(String fileName,String uri){ this.fileName = fileName; this.uri = uri; uploadFile= new File(fileName); mTtotalSize = uploadFile.length(); } /** * 開始上傳文件 * @param objects * @return */ @Override protected Void doInBackground(Object... objects) { long length = 0; int mBytesRead, mbytesAvailable, mBufferSize; byte[] buffer; int maxBufferSize = 256 * 1024;// 256KB try{ FileInputStream fileInputStream = new FileInputStream(new File(fileName)); URL url = new URL(uri); HttpURLConnection con = (HttpURLConnection) url.openConnection(); //若是有必要則能夠設置Cookie // conn.setRequestProperty("Cookie","JSESSIONID="+cookie); // Set size of every block for post con.setChunkedStreamingMode(256 * 1024);// 256KB // Allow Inputs & Outputs con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // Enable POST method con.setRequestMethod("POST"); con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); outputStream = new DataOutputStream( con.getOutputStream()); outputStream.writeBytes(mTwoHyphens + boundary + mLineEnd); outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + mLineEnd); outputStream.writeBytes("Content-Type:application/octet-stream \r\n"); outputStream.writeBytes(mLineEnd); mbytesAvailable = fileInputStream.available(); mBufferSize = Math.min(mbytesAvailable, maxBufferSize); buffer = new byte[mBufferSize]; // Read file mBytesRead = fileInputStream.read(buffer, 0, mBufferSize); while (mBytesRead > 0) { outputStream.write(buffer, 0, mBufferSize); length += mBufferSize; publishProgress((int) ((length * 100) / mTtotalSize)); mbytesAvailable = fileInputStream.available(); mBufferSize = Math.min(mbytesAvailable, maxBufferSize); mBytesRead = fileInputStream.read(buffer, 0, mBufferSize); } outputStream.writeBytes(mLineEnd); outputStream.writeBytes(mTwoHyphens + boundary + mTwoHyphens + mLineEnd); publishProgress(100); // Responses from the server (code and message) int serverResponseCode = con.getResponseCode(); String serverResponseMessage = con.getResponseMessage(); fileInputStream.close(); outputStream.flush(); outputStream.close(); } catch (Exception ex) { ex.printStackTrace(); Log.v(TAG,"uploadError"); } return null; } @Override protected void onProgressUpdate(Integer... progress) { mPgBar.setProgress(progress[0]); } }
主要流程爲繼承AsyncTask,而後使用HttpURLConnection 去上傳文件。代碼比較簡單,就不一一講解了。框架
其中要注意的是須要在ide
outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + mLineEnd);
將name 設置爲web 請求的參數名,因爲個人服務端是將文件設置爲file參數,因此我能夠直接填file .因此你們能夠根據實際狀況做相應修改。post
那麼接着上服務端代碼,服務端主要使用status 2框架做請求。那麼咱們就須要進行封裝。測試
//上傳文件集合 private List<File> file; //上傳文件名集合 private List<String> fileFileName; //上傳文件內容類型集合 private List<String> fileContentType; public List<File> getFile() { return file; } public void setFile(List<File> file) { this.file = file; } public List<String> getFileFileName() { return fileFileName; } public void setFileFileName(List<String> fileFileName) { this.fileFileName = fileFileName; } public List<String> getFileContentType() { return fileContentType; } public void setFileContentType(List<String> fileContentType) { this.fileContentType = fileContentType; }
採用了多文件上傳的方法,定義了List 集合。this
那麼處理文件上傳的action ,因爲是測試方法。這裏就定義爲testUpload編碼
public String testUpload()throws Exception{ System.out.println("success"); uploadFile(0); return SUCCESS; }
到這裏就已經才很少完成動做了,如今須要開始寫上傳的方法 uploadFile(int index),因爲定義file 爲多文件上傳,而咱們上傳只上傳了一個文件,因此這裏參數爲0
/** * 上傳功能 * @param i * @return * @throws FileNotFoundException * @throws IOException */ private String uploadFile(int i) throws FileNotFoundException, IOException { try { InputStream in = new FileInputStream(file.get(i)); //String dir = ServletActionContext.getRequest().getRealPath(UPLOADDIR); String dir = "D://UploadData/"; File uploadFile = new File(dir,StringUtils.getUUID()+getFile( this.getFileFileName().get(i))); OutputStream out = new FileOutputStream(uploadFile); byte[] buffer = new byte[1024 * 1024]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } in.close(); out.close(); //而後進行計算 return uploadFile.getAbsolutePath(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } return null; }
上面方法爲將緩存區域的文件 而後搞到了D://UploadData/ 文件中,而後以本身的格式進行命名,這裏我使用了電腦的UUID和文件名進行組合,確保我複製過來的文件不重複。
最後上傳成功以後返回文件的真實地址。
ok,寫到這裏上傳文件的功能基本上作完了。最後只剩下配置action 動做。
ok,咱們打開status.xml 文件進行配置
<!-- 系統常量定義,定義上傳文件字符集編碼 --> <constant name="struts.i18n.encoding" value="utf-8"></constant> <!-- 系統常量定義,定義上傳文件零時存放路徑 --> <constant name="struts.multipart.saveDir" value="c:\tmp\"></constant> <constant name="struts.multipart.maxSize" value="10000000" />
這裏主要定義上傳文件的臨時存放位置,而後大小限制。
你們能夠根據實際狀況進行配置。
最後上傳一張效果圖。