String urlString = "***"; String params = "{****}"; URL url; try { url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0"); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setConnectTimeout(1000 * 5); conn.getOutputStream().write(params.getBytes("utf8")); conn.getOutputStream().flush(); conn.getOutputStream().close(); byte[] buffer = new byte[1024]; StringBuffer sb = new StringBuffer(); InputStream in = conn.getInputStream(); int httpCode = conn.getResponseCode(); System.out.println(in.available()); while(in.read(buffer,0,1024) != -1) { sb.append(new String(buffer)); } System.out.println("sb:" + sb.toString()); in.close(); System.out.println(httpCode); }catch(Exception e) { e.printStackTrace(); }
让我很是头疼,我知道对于高手来说这不是什么难题。
2.然后我用了apache开源的httpclient试了一下,结果很顺利的返回了200,让我琢磨不透。因为我一直很抵触开源的东西(尤其是ssh),能自己写的就尽量自己写,所以我还得花点时间在HttpURLConnection上。
用httpClient写的post
String result = null; // 创建HttpClientBuilder HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); // HttpClient CloseableHttpClient closeableHttpClient = httpClientBuilder.build(); HttpPost httpPost = new HttpPost(url); StringEntity stringEntity = new StringEntity(params,ContentType.create("plain/text", Consts.UTF_8)); httpPost.setEntity(stringEntity); System.out.println(httpPost.getRequestLine()); try { // 执行get请求 HttpResponse httpResponse = closeableHttpClient.execute(httpPost); // 获取响应消息实体 HttpEntity entity = httpResponse.getEntity(); // 响应状态 System.out.println("status:" + httpResponse.getStatusLine()); // 判断响应实体是否为空 if (entity != null) { System.out.println("contentEncoding:" + entity.getContentEncoding()); System.out.println("response content:"+ EntityUtils.toString(entity)); } } catch (IOException e) { throw e; } finally { try { // 关闭流并释放资源 closeableHttpClient.close(); } catch (IOException e) { throw e; } }
那就抓包看看究竟哪里出问题吧,结果一抓很容易就看出了两者的不同。
Content-Type: plain/text; charset=UTF-8就差这个头上了。把这个加到HttpURLConnection里结果就ok了
conn.setRequestProperty("Content-Type", "plain/text; charset=UTF-8");
Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。
所以Content-Type 字段还是很重要的,在调用前一定要知道对方是什么编码,这样可以节省时间。
4.其实今天主要说的不是这个问题,而是抓包的时候发现了新的知识点。就是HttpURLConnection何时发送请求?
看了看用HttpURLConnection写的post代码,简直一头污水,还是配合Wireshark查看更清楚一些。
eclipse里设置好了断点,开始debug,另一边用wireshark抓包,结果是这样的。
当执行完output.flush的时候,HttpURLConnection才开始与对方建立三次握手。
wireshark里
当执行conn.getInputStream()的时候才开始发送数据
eclipse里
wireshark里
5.总结
5.1 写http客户端一定要先约定好编码格式。
5.2 在HttpURLConnection post时,flush后建立连接,getInputstream时提交数据。
写的不好,请批评指正。