Java 网络编程封装原理主要围绕着将底层的网络通信细节隐藏起来,提供简洁、易用且安全的高层接口,方便开发者进行网络应用开发。下面从封装的目标、常见的封装层次和具体的封装实现原理等方面详细介绍。
封装的目标
简化开发:底层的网络通信涉及到许多复杂的细节,如套接字的创建、连接的建立、数据的传输和接收等。通过封装,开发者可以使用更简单的接口来完成这些操作,无需关心底层的具体实现。
提高安全性:封装可以对网络通信的关键部分进行安全处理,例如对数据进行加密、验证等,防止数据在传输过程中被窃取或篡改。
增强可维护性和可扩展性:将网络通信的逻辑封装在独立的模块中,使得代码结构更加清晰,便于维护和扩展。当需要更改网络通信的实现方式时,只需修改封装模块的内部代码,而不会影响到使用该封装的其他部分。
常见的封装层次
套接字层封装
Java 的 java.net 包提供了基本的套接字(Socket)类,包括 Socket 和 ServerSocket,用于实现 TCP 通信,以及 DatagramSocket 用于实现 UDP 通信。这些类已经对底层的网络操作进行了一定程度的封装,但仍然需要开发者手动处理很多细节。例如,创建一个简单的 TCP 服务器:
代码如下:
package cn.ctg.common.util;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Map;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
/**
* http请求
*/
@Slf4j
public class HttpUtils {
public static String doGet(String url) {
return doGet(url, null);
}
public static String doGet(String url, Map<String, String> map) {
String resultString = "";
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
// 参数设置
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
if (CollectionUtil.isNotEmpty(map)) {
for (String key : map.keySet()) {
params.add(key, map.get(key));
}
}
try {
// 设置表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
params, headers);
// 执行HTTP请求
ResponseEntity<String> response = client.exchange(url, HttpMethod.GET, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPost(String url, Map<String, String> map) {
String resultString = "";
ResponseEntity<String> response = null;
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
// 参数设置
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
if (CollectionUtil.isNotEmpty(map)) {
for (String key : map.keySet()) {
params.add(key, map.get(key));
}
}
try {
// 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
params, headers);
// 执行HTTP请求
response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return resultString;
}
public static String doPostJson(String url, String json) {
String resultString = "";
RestTemplate client = new RestTemplate();
ResponseEntity<String> response = null;
// 提交方式设置
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<String>(json, headers);
try {
// 执行HTTP请求
response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
resultString = response.getBody();
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
try {
} catch (Exception e) {
// TODO Auto-generated catch block
log.error(e.getMessage(), e);
}
}
return resultString;
}
/**
* 创建http请求头
* @param url
* @return
* @throws Exception
*/
public static URLConnection FactoryCreatURLConnection(String url) throws Exception {
URL realUrl;
URLConnection conn = null;
try {
// 打开和URL之间的连接
realUrl = new URL(url);
conn = realUrl.openConnection();
conn.setRequestProperty("accept", "text/plain;charset=utf-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return conn;
}
/**
* 判断连接是否可用
*
* @param url http请求地址
* @return
*/
public static boolean isRearchUrl(String url) {
return isRearchUrl(url, 3000);
}
/**
* 判断连接是否可用
*
* @param url http请求地址
* @return
*/
public static boolean isRearchUrl(String url, int timeout) {
if (StringUtils.isEmpty(url)) {
return false;
}
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
// 设置超时时间
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
if (connection.getResponseCode() >= HttpURLConnection.HTTP_OK
&& connection.getResponseCode() <= HttpURLConnection.HTTP_VERSION) {
return true;
}
} catch (Exception e) {
log.error(" HttpURLConnection exception happend!");
return false;
} finally {
if (connection != null) {
connection.disconnect();
}
}
return false;
}
/**
* 判断ip是否能ping通
*/
public static boolean checkIp(String ipAddr) {
try {
boolean status = false;
if (!StringUtils.isEmpty(ipAddr)) {
int timeOut = 3000; // 超时 3秒
status = InetAddress.getByName(ipAddr).isReachable(timeOut);
return status;
}
return status;
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}