1.此例子看考:https://blog.csdn.net/Jane_Liee/article/details/78527859,代码没复制全,因为只为解释。
java.net包是用于网络连接使用的。她的原理是:通过本地请求信息将本地tcp套接字和目标地套接字连接起来。一旦建立连接,双方都会对自己的套接字监听,一旦有数据进入会立刻发现并处理。所以,当我们的请求信息被写入到对方的套接字中时对方会立即拿到并通过我们连接写入到我们的套接字中,此时我们会立即拿到对方写入(响应)的信息。从对方将信息写入到我们的套接字后便主动断开连接,我们也会随之断开连接。这就是底层的交互方式,是用c语言写的,jdk进过对这些底层的方法进行封装后提供给我们的就是java.net包下的封装。
下列方法的流程就是:先通过URL打开双方的连接(著名的3次握手就是这时候做的) -> 填写请求数据 -> 将数据刷新到对方的套接字中 -> 对方收到请求信息后 -> 再将响应返回到请求的套接字中,然后关闭套接字直接的连接(即释放对方的地址内容) -> 此时请求放从自己的套接字中拿到了响应信息,也释放了自己套接字中对方的套接字信息。这就是一次完整的http请求
简单来说就是:我将我的请求信息给我的套接字,然后我的套接字将请求信息写入对方的套接字,之后对方又将响应的信息写入到我的套接字,然后双方关闭连接。
所以有了以上的定论:那么下列代码中就很好解释了,URL开启连接后再赋值最后刷新到对方去,然后等待对方刷新到我们这儿来后就有读取。其中用到的conn.getOutputStream()就是往对方套接字中写数据的流(序列化),之后的out.flush();就是将缓存中的请求数据都刷新到对方套接字中去。在刷新到对方套接字中去后会主动等待对方回来,在conn.getInputStream()的时候对方消息已经回来了并且对方也已经关闭连接了。如果对方没消息也会回来一个异常消息。此时就可以通过输入流(反序列化)conn.getInputStream()来读取本地套接字中对方返回的内容了。
1.示例1:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sf.json.JSONObject; public static JSONObject sendPost(String url,Map<String, Object> paramMap){ JSONObject jsonObj = null; if(url != "https:/Your URL!"){ //获取token,这里是OAuth 2.0认证 paramMap.put("access_token", getToken()); } try { URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); //指定客户端能够接收的内容类型 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive");//设置连接的状态 //User-Agent的内容包含发出请求的用户信息 conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Charset", "UTF-8"); conn.setDoOutput(true); conn.setDoInput(true); PrintWriter out = new PrintWriter(conn.getOutputStream()); String param = mapToParam(paramMap); out.print(param); out.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; String str = ""; while ((line = in.readLine()) != null) { str += line; } jsonObj = JSONObject.fromObject(str); } catch (MalformedURLException e) { System.err.println("URL协议、格式或者路径错误!" + e); e.printStackTrace(); } catch (IOException e) { System.err.println("URL连接失败!" + e); e.printStackTrace(); } catch (Exception e) { System.err.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } return jsonObj; }
2.示例2:这个是apache提供的库:一样的流程和功能,只是提供的更加优雅而已,但是越优雅的东西限制就会越大,大到你无法改动或难于理解底层,其实他这个也一样:我们可以看到上面URL做的事情在这换成了HttpClient,而请求方式,消息头参数也都提供了专门的方法:请求方法:PostMethod ,请求参数:RequestEntity ,上面的刷新(序列化)对应这边的httpClient.executeMethod(post);最后的读取(反序列化)和上面差不多
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSONObject; public static JSONObject post(String url, JSONObject requestInfo) throws HttpException, IOException { String path = "/api/jobinfo/save"; String targetUrl = url + path; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(targetUrl); RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8"); post.setRequestEntity(requestEntity); httpClient.executeMethod(post); JSONObject result = new JSONObject(); result = getJsonObject(post, result); return result; } private static JSONObject getJsonObject(HttpMethod get, JSONObject result) throws IOException { InputStream inputStream = get.getResponseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); StringBuffer stringBuffer = new StringBuffer(); String str = ""; while ((str = br.readLine()) != null) { stringBuffer.append(str); } if (get.getStatusCode() == 200) { result = JSONObject.parseObject(stringBuffer.toString()); } else { try { result = JSONObject.parseObject(stringBuffer.toString()); } catch (Exception e) { result.put("error", stringBuffer.toString()); } } br.close(); inputStream.close(); return result; }
示例3:apache提供
import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; private static String sendPostRequest(String reqURL, String json, String encoding, String authorization) { HttpPost httpPost = new HttpPost(reqURL); CloseableHttpClient httpClient = HttpClientUtil.getConnection(); HttpResponse response = null; String result = ""; try { StringEntity entity = new StringEntity(json, encoding); entity.setContentType("application/json"); httpPost.setEntity(entity); httpPost.setHeader("Authorization", authorization.trim()); response = httpClient.execute(httpPost); result = EntityUtils.toString(response.getEntity(), encoding); } catch (Exception e) { log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e); } return result; }
示例4:okhttp3提供:请求流程一样,原理也一样,这种编码方式到比较好,自由操作度高,没有acache封装的那么狠,但是需要了解http请求中的每个字段方可操作,越熟悉越厉害嘛。这个里面还提供了用于http请求的线程池。这是很好的设计。
import java.util.concurrent.TimeUnit; import com.google.common.collect.Maps; import okhttp3.ConnectionPool; import okhttp3.ConnectionSpec; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; private static ConnectionPool pool = null; static { pool = new ConnectionPool(100, 20, TimeUnit.MINUTES); } public static String sendGetBindPlayer(String cookie, String url) throws IOException { OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(3000L, TimeUnit.MILLISECONDS) .readTimeout(3000L, TimeUnit.MILLISECONDS) .connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS)) .connectionPool(pool).build(); Request.Builder requestBuilder = new Request.Builder().url(url).addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36 qblink tgp_daemon.exe QBCore/3.43.812.400 QQBrowser/9.0.2524.400") .addHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.5;q=0.4") .addHeader("Accept", "image/sharpp,*/*"); Map<String, List<String>> map = getMap(cookie); for (String key : map.keySet()) { for (String value : map.get(key)) { requestBuilder.addHeader(key, value); } } Request request = requestBuilder.build(); Response response = okHttpClient.newCall(request).execute(); if (response.isSuccessful()) { String result = response.body().string();// 结果 return result; } else { throw new IOException("Unexpected code " + response); } }