Android 开发工具类 32_通过 HTTP 协议实现文件上传

完成像带有文件的用户数据表单的上传,而且可以上传多个文件,这在用户注册并拍照时尤其有用。

  1 import java.io.BufferedReader;
  2 import java.io.ByteArrayOutputStream;
  3 import java.io.DataOutputStream;
  4 import java.io.InputStream;
  5 import java.io.InputStreamReader;
  6 import java.io.OutputStream;
  7 import java.net.HttpURLConnection;
  8 import java.net.InetAddress;
  9 import java.net.Socket;
 10 import java.net.URL;
 11 import java.net.URLEncoder;
 12 import java.util.ArrayList;
 13 import java.util.List;
 14 import java.util.Map;
 15 
 16 import org.apache.http.HttpResponse;
 17 import org.apache.http.NameValuePair;
 18 import org.apache.http.client.HttpClient;
 19 import org.apache.http.client.entity.UrlEncodedFormEntity;
 20 import org.apache.http.client.methods.HttpPost;
 21 import org.apache.http.impl.client.DefaultHttpClient;
 22 import org.apache.http.message.BasicNameValuePair;
 23 
 24 public class HTTPPost {
 25 
 26     /**
 27      * 直接通过 HTTP 协议提交数据到服务器,实现如下表单提交功能
 28      * <FORM METHOD=POST ACTION="http://192.168.1.103:8080/ssi/fileload/test.do"
 29      * enctype="multipart/form-data">
 30      * <INPUT TYPE="text" NAME="name">
 31      * <INPUT TYPE="text" NAME="id">
 32      * <INPUT TYPE="file" name="imagefile"/>
 33      * <INPUT TYPE="file" name="zip"/>
 34      * </FORM>
 35      */
 36     //enum FormFile;
 37     /*
 38      * @parm path 上传路径(注:避免使用 localhost 或 127.0.0.1这样的路径测试,
 39      * 因为它会指向手机模拟器,可以使用 http://192.168.1.103:8080 这样的路径测试)
 40      * @parm parms 请求参数 key 为参数名,value 为参数值
 41      * @parm file 上传文件
 42      */
 43     public static boolean post(String path, Map<String, String>params, FormFile[] files) throws Exception{
 44         
 45         final String BOUNDARY = "-----------------------------" +
 46                 "7da2137580612"; // 数据分割线
 47         final String endline = "--"+BOUNDARY+"--
";  // 数据结束标志
 48         int fileDataLength = 0;
 49         
 50         for(FormFile uploadFile : files){
 51             // 得到文件类型数据的总长度
 52             StringBuilder fileExplain = new StringBuilder();
 53             fileExplain.append("--");
 54             fileExplain.append(BOUNDARY);
 55             fileExplain.append("
");
 56             fileExplain.append("Content-Dispostion: form-data;name="" +
 57                     uploadFile.getParameterName()+"";filename=""+
 58                     uploadFile.getFilname()+""
");
 59             fileExplain.append("Content-Type: "+
 60                     uploadFile.getContentType()+"

");
 61             fileExplain.append("
");
 62             
 63             fileDataLength += fileExplain.length();
 64             if(uploadFile.getInStream()!=null){
 65                 fileDataLength += uploadFile.getFile().length();
 66             }else{
 67                 fileDataLength += uploadFile.getData().length;
 68             }
 69         }
 70         StringBuilder textEntry = new StringBuilder();
 71         for(Map.Entry<String, String> entry : params.entrySet()){
 72             // 构造文本类型参数的实体数据
 73             textEntry.append("--");
 74             textEntry.append(BOUNDARY);
 75             textEntry.append("
");
 76             textEntry.append("Content-Disposition: form-data; name=""+
 77                             entry.getKey()+""

");
 78             textEntry.append(entry.getValue());
 79             textEntry.append("
");
 80         }
 81         // 计算传输给服务器的实体数据总长度
 82         int datalength = textEntry.toString().getBytes().length +
 83                 fileDataLength + endline.getBytes().length;
 84         URL url = new URL(path);
 85         int port = url.getPort() == -1 ? 80 : url.getPort();
 86         Socket socket = new Socket(InetAddress.getByName(url.getHost()),port);
 87         OutputStream outStream = socket.getOutputStream();
 88         // 下面完成 HTTP 请求头的发送
 89         String requestmethod = "POST" + url.getPath()+"HTTP/1.1
";
 90         outStream.write(requestmethod.getBytes());
 91         String accept = "Accept: image/gif, image/jpeg, image/pjpeg," +
 92                 "image/pjpeg, application/x-shockwave-flash, application/xaml+xml," +
 93                 "application/vnd.ms-xpsdocument, application/x-ms-xbap," +
 94                 "application/x-ms-application, application/vnd.ms-excel," +
 95                 "application/vnd.ms-powerpoint, application/msword, */*
";
 96         outStream.write(accept.getBytes());
 97         String language = "Accept-Language: zh-CN
";
 98         outStream.write(language.getBytes());
 99         String contenttype = "Content-Type: multipart/form-data;boundary="+
100                         BOUNDARY + "
";
101         outStream.write(contenttype.getBytes());
102         String contentlength = "Content-Length: "+ datalength + "
";
103         outStream.write(contentlength.getBytes());
104         String alive = "Connection: Keep-Alive
";
105         outStream.write(alive.getBytes());
106         String host = "Host:" + url.getHost() + ":" + port + "
";
107         outStream.write(host.getBytes());
108         // 写完 HTTP 请求头后根据 HTTP 协议再写一个回车换行
109         outStream.write("
".getBytes());
110         // 把所有文本类型的实体数据发送出来
111         outStream.write(textEntry.toString().getBytes());
112         // 把所有文件类型的实体数据发送出来
113         for(FormFile uploadFile : files){
114             StringBuilder fileEntity = new StringBuilder();
115             fileEntity.append("--");
116             fileEntity.append(BOUNDARY);
117             fileEntity.append("
");
118             fileEntity.append("Content-Disposition: form-data;name=""+
119                             uploadFile.getParameterName()+"";filename=""+
120                             uploadFile.getFilname()+""
");
121             fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"

");
122             outStream.write(fileEntity.toString().getBytes());
123             if(uploadFile.getInStream() != null){
124                 byte[] buffer = new byte[1024];
125                 int len = 0;
126                 while((len = uploadFile.getInStream().read(buffer,0,1024)) != -1){
127                     outStream.write(buffer, 0, len);
128                 }
129                 uploadFile.getInStream().close();
130             }else{
131                 outStream.write(uploadFile.getData(),0,uploadFile.getData().length);
132             }
133             outStream.write("
".getBytes());
134         }
135         // 下面发送数据结束标志,表示数据已经结束
136         outStream.write(endline.getBytes());
137         BufferedReader reader = new BufferedReader(new 
138                 InputStreamReader(socket.getInputStream()));
139         if(reader.readLine().indexOf("200") == -1){
140             // 读取 Web 服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败
141             return false;
142         }
143         outStream.flush();
144         outStream.close();
145         reader.close();
146         socket.close();
147         return true;
148     }
149     
150     /**
151      * 提交数据到服务器
152      * @param path 上传路径
153      * @param params 请求参数 key 为参数名, value 为参数值
154      * @param file 上传文件
155      */
156     public static boolean post(String path, Map<String, String> params, FormFile file)
157             throws Exception{
158         return post(path, params, new FormFile[]{file});
159     }
160     
161     /**
162      * 提交数据到服务器
163      * @param path 上传路径
164      * @param params 请求参数 key 为参数名, value 为参数值
165      * @param encode 编码
166      */
167     public static byte[] postFromHttpClient(String path, Map<String, String> params, String encode) throws Exception{
168         
169         List<NameValuePair> formparams = new ArrayList<NameValuePair>();
170         // 用于存放请求参数
171         for(Map.Entry<String, String> entry : params.entrySet()){
172             formparams.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
173         }
174         UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encode);
175         HttpPost httppost = new HttpPost(path);
176         httppost.setEntity(entity);
177         HttpClient httpclient = new DefaultHttpClient();
178         HttpResponse response = httpclient.execute(httppost);
179         // 发送 post 请求
180         return readStream(response.getEntity().getContent());
181     }
182     
183     /**
184      * 发送 请求
185      * @param path 请求路径
186      * @param params 请求参数 key 为参数名, value 为参数值
187      * @param encode 请求参数的编码
188      */
189     public static byte[] post(String path, Map<String, String> params, String encode)throws Exception{
190         //String params = "method=save&name="+URLEncoder.encode("老毕","UTF-8")+"&age=28&"; 
191         // 需要发送的参数
192         StringBuilder parambuilder = new StringBuilder(""); 
193         if(params != null && !params.isEmpty()){
194             for(Map.Entry<String, String> entry : params.entrySet()){
195                 parambuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(),encode)).append("&");                
196             }
197             parambuilder.deleteCharAt(parambuilder.length()-1);
198         }
199         byte[] data = parambuilder.toString().getBytes();
200         URL url = new URL(path);
201         HttpURLConnection conn = (HttpURLConnection)url.openConnection();
202         conn.setDoOutput(true);
203         conn.setUseCaches(false);
204         conn.setConnectTimeout(5*1000);
205         conn.setRequestMethod("POSST");
206         // 下面设置 http 请求头
207         conn.setRequestProperty("Accept", "image/gif, image/jpeg," +
208                 "image/pjpeg, image/pjpeg, application/x-shockwave-flash," +
209                 "application/xaml+xml, application/vnd.ms-xpsdocument," +
210                 "application/x-ms-xbap, application/x-ms-application," +
211                 "application/vnd.ms-excel, application/vnd.ms-powerpoint," +
212                 "application/msword, */*");
213         conn.setRequestProperty("Accept-Language", "zh-CN");
214         conn.setRequestProperty("User-Agent", "Mozilla/4.0 " +
215                 "(compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR" +
216                 "1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR" +
217                 "3.0.4506.2152; .NET CLR 3.5.30729)");
218         conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
219         conn.setRequestProperty("Content-Length", String.valueOf(data.length));
220         conn.setRequestProperty("Connection", "Keep-Alive");
221         // 发送参数
222         DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
223         // 发送
224         outStream.write(data);
225         outStream.flush();
226         outStream.close();
227         if(conn.getResponseCode() == 200){
228             return readStream(conn.getInputStream());
229         }
230         return null;
231     }
232     
233     /**
234      * 读取流
235      * @param inStream
236      * @return 字节数组
237      * @throws Exception
238      */
239     public static byte[] readStream(InputStream inStream)throws Exception{
240         
241         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
242         byte[] buffer = new byte[1024];
243         int len = -1;
244         while((len = inStream.read(buffer)) != -1){
245             outStream.write(buffer, 0, len);
246         }
247         outStream.close();
248         inStream.close();
249         return outStream.toByteArray();
250     }
251         
252 }
原文地址:https://www.cnblogs.com/renzimu/p/4542503.html