完成像带有文件的用户数据表单的上传,而且可以上传多个文件,这在用户注册并拍照时尤其有用。
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+"--\r\n"; // 数据结束标志 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("\r\n"); 56 fileExplain.append("Content-Dispostion: form-data;name=\"" + 57 uploadFile.getParameterName()+"\";filename=\""+ 58 uploadFile.getFilname()+"\"\r\n"); 59 fileExplain.append("Content-Type: "+ 60 uploadFile.getContentType()+"\r\n\r\n"); 61 fileExplain.append("\r\n"); 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("\r\n"); 76 textEntry.append("Content-Disposition: form-data; name=\""+ 77 entry.getKey()+"\"\r\n\r\n"); 78 textEntry.append(entry.getValue()); 79 textEntry.append("\r\n"); 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\r\n"; 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, */*\r\n"; 96 outStream.write(accept.getBytes()); 97 String language = "Accept-Language: zh-CN\r\n"; 98 outStream.write(language.getBytes()); 99 String contenttype = "Content-Type: multipart/form-data;boundary="+ 100 BOUNDARY + "\r\n"; 101 outStream.write(contenttype.getBytes()); 102 String contentlength = "Content-Length: "+ datalength + "\r\n"; 103 outStream.write(contentlength.getBytes()); 104 String alive = "Connection: Keep-Alive\r\n"; 105 outStream.write(alive.getBytes()); 106 String host = "Host:" + url.getHost() + ":" + port + "\r\n"; 107 outStream.write(host.getBytes()); 108 // 写完 HTTP 请求头后根据 HTTP 协议再写一个回车换行 109 outStream.write("\r\n".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("\r\n"); 118 fileEntity.append("Content-Disposition: form-data;name=\""+ 119 uploadFile.getParameterName()+"\";filename=\""+ 120 uploadFile.getFilname()+"\"\r\n"); 121 fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n"); 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("\r\n".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 }
时间: 2024-10-30 08:39:57