java中所有的网络请求方法和拦截器
//使用OkHttp请求是一个流行的第三方库通常用于更高效的 HTTP 请求特别是在 Android 开发中非常常见。 import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class OkHttpExample { public static void main(String[] args) { OkHttpClient client new OkHttpClient(); // 创建请求对象 Request request new Request.Builder() .url(https://api.github.com) .build(); try (Response response client.newCall(request).execute()) { // 打印响应内容 System.out.println(Response Code: response.code()); System.out.println(Response Body: response.body().string()); } catch (Exception e) { e.printStackTrace(); } } } //使用 HttpURLConnection 类, 是 Java 标准库提供的一个类用于处理 HTTP 请求。这是一个较为基础的 HTTP 请求方式。 import java.io.*; import java.net.*; public class HttpURLConnectionExample { public static void main(String[] args) throws Exception { URL url new URL(http://example.com); HttpURLConnection connection (HttpURLConnection) url.openConnection(); connection.setRequestMethod(GET); // 读取响应 BufferedReader in new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response new StringBuffer(); while ((inputLine in.readLine()) ! null) { response.append(inputLine); } in.close(); System.out.println(response.toString()); } } //Apache HttpClient是一个功能强大的 HTTP 请求库提供了更加丰富的功能和更好的性能。通常在大型应用中使用。 import org.apache.http.HttpEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpResponse; import org.apache.http.util.EntityUtils; public class HttpClientExample { public static void main(String[] args) throws Exception { try (CloseableHttpClient httpClient HttpClients.createDefault()) { HttpGet request new HttpGet(http://example.com); try (CloseableHttpResponse response httpClient.execute(request)) { HttpEntity entity response.getEntity(); String result EntityUtils.toString(entity); System.out.println(result); } } } } //Java 11 引入了 HttpClient API作为 HttpURLConnection 的替代提供了更现代、更简洁的方式来发送 HTTP 请求。 import java.net.URI; import java.net.http.*; import java.net.http.HttpRequest.*; import java.util.concurrent.*; public class HttpClientExampleJava11 { public static void main(String[] args) throws Exception { HttpClient client HttpClient.newHttpClient(); HttpRequest request HttpRequest.newBuilder() .uri(new URI(http://example.com)) .build(); HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); } } //RestTemplate 是 Spring 提供的用于简化 HTTP 请求的工具类。它支持多种 HTTP 方法GET、POST、PUT、DELETE 等和 JSON 解析等。 import org.springframework.web.client.RestTemplate; public class RestTemplateExample { public static void main(String[] args) { RestTemplate restTemplate new RestTemplate(); String result restTemplate.getForObject(http://example.com, String.class); System.out.println(result); } } //URLConnection简单实现URLConnection 是 HttpURLConnection 的父类可以用于发送 HTTP 请求但它的功能没有 HttpURLConnection 那么强大。 import java.io.*; import java.net.*; public class URLConnectionExample { public static void main(String[] args) throws Exception { URL url new URL(http://example.com); URLConnection connection url.openConnection(); // 获取响应 BufferedReader in new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response new StringBuffer(); while ((inputLine in.readLine()) ! null) { response.append(inputLine); } in.close(); System.out.println(response.toString()); } } // Jetty Client较少使用Jetty 是一个 Java Web 服务器但它也提供了 Jetty Client 用于进行 HTTP 请求。它主要用于与 Jetty 服务器的集成但也可以独立使用。 import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.util.ssl.SslContextFactory; public class JettyClientExample { public static void main(String[] args) throws Exception { HttpClient client new HttpClient(new SslContextFactory.Client()); client.start(); client.GET(http://example.com) .onResponse(response - { System.out.println(response.getContentAsString()); }) .send(); client.stop(); } } //AsyncHttpClient较少使用AsyncHttpClient 是一个异步 HTTP 客户端库主要用于异步的网络请求处理。 import org.asynchttpclient.*; public class AsyncHttpClientExample { public static void main(String[] args) throws Exception { AsyncHttpClient client Dsl.asyncHttpClient(); client.prepareGet(http://example.com) .execute() .toCompletableFuture() .thenAccept(response - { System.out.println(response.getResponseBody()); }).join(); client.close(); } } //JDK 8 CompletableFuture 与 HttpClient异步请求结合 JDK 8 的 CompletableFuture 和 Java 11 的 HttpClient 可以轻松实现异步请求。 import java.net.URI; import java.net.http.*; import java.util.concurrent.*; public class AsyncHttpClientJava11 { public static void main(String[] args) throws Exception { HttpClient client HttpClient.newHttpClient(); HttpRequest request HttpRequest.newBuilder() .uri(new URI(http://example.com)) .build(); CompletableFutureHttpResponseString responseFuture client.sendAsync(request, HttpResponse.BodyHandlers.ofString()); responseFuture.thenAccept(response - System.out.println(response.body())); } }import android.util.Base64 import java.security.KeyFactory import java.security.KeyPairGenerator import java.security.MessageDigest import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.X509EncodedKeySpec import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.Mac import javax.crypto.SecretKeyFactory import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.PBEKeySpec import javax.crypto.spec.SecretKeySpec // // AES 加密 / 解密 // object AESUtils { private const val ALGORITHM AES private const val TRANSFORMATION_CBC AES/CBC/PKCS5Padding private const val TRANSFORMATION_ECB AES/ECB/PKCS5Padding private const val TRANSFORMATION_GCM AES/GCM/NoPadding /** 生成 AES 密钥128 / 192 / 256 位 */ fun generateKey(keySize: Int 256): ByteArray { val keyGen KeyGenerator.getInstance(ALGORITHM) keyGen.init(keySize) return keyGen.generateKey().encoded } // ---------- CBC 模式 ---------- /** AES-CBC 加密返回 Base64 字符串IV 拼接在密文前 */ fun encryptCBC(plainText: String, keyBytes: ByteArray): String { val iv ByteArray(16).also { java.security.SecureRandom().nextBytes(it) } val cipher Cipher.getInstance(TRANSFORMATION_CBC) cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(keyBytes, ALGORITHM), IvParameterSpec(iv)) val encrypted cipher.doFinal(plainText.toByteArray(Charsets.UTF_8)) // 将 IV 拼接到密文头部方便解密时提取 return Base64.encodeToString(iv encrypted, Base64.NO_WRAP) } /** AES-CBC 解密 */ fun decryptCBC(cipherBase64: String, keyBytes: ByteArray): String { val data Base64.decode(cipherBase64, Base64.NO_WRAP) val iv data.copyOfRange(0, 16) val encrypted data.copyOfRange(16, data.size) val cipher Cipher.getInstance(TRANSFORMATION_CBC) cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(keyBytes, ALGORITHM), IvParameterSpec(iv)) return String(cipher.doFinal(encrypted), Charsets.UTF_8) } // ---------- ECB 模式不推荐用于生产IV 固定 ---------- fun encryptECB(plainText: String, keyBytes: ByteArray): String { val cipher Cipher.getInstance(TRANSFORMATION_ECB) cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(keyBytes, ALGORITHM)) return Base64.encodeToString(cipher.doFinal(plainText.toByteArray()), Base64.NO_WRAP) } fun decryptECB(cipherBase64: String, keyBytes: ByteArray): String { val cipher Cipher.getInstance(TRANSFORMATION_ECB) cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(keyBytes, ALGORITHM)) return String(cipher.doFinal(Base64.decode(cipherBase64, Base64.NO_WRAP))) } } // // RSA 加密 / 解密 / 签名 / 验签 // object RSAUtils { private const val ALGORITHM RSA private const val TRANSFORMATION RSA/ECB/PKCS1Padding private const val SIGN_ALGORITHM SHA256withRSA private const val KEY_SIZE 2048 data class RsaKeyPair(val publicKeyBase64: String, val privateKeyBase64: String) /** 生成 RSA 密钥对 */ fun generateKeyPair(): RsaKeyPair { val kpg KeyPairGenerator.getInstance(ALGORITHM) kpg.initialize(KEY_SIZE) val kp kpg.generateKeyPair() return RsaKeyPair( publicKeyBase64 Base64.encodeToString(kp.public.encoded, Base64.NO_WRAP), privateKeyBase64 Base64.encodeToString(kp.private.encoded, Base64.NO_WRAP) ) } /** 公钥加密 */ fun encryptByPublicKey(plainText: String, publicKeyBase64: String): String { val keyBytes Base64.decode(publicKeyBase64, Base64.NO_WRAP) val publicKey KeyFactory.getInstance(ALGORITHM) .generatePublic(X509EncodedKeySpec(keyBytes)) val cipher Cipher.getInstance(TRANSFORMATION) cipher.init(Cipher.ENCRYPT_MODE, publicKey) return Base64.encodeToString(cipher.doFinal(plainText.toByteArray()), Base64.NO_WRAP) } /** 私钥解密 */ fun decryptByPrivateKey(cipherBase64: String, privateKeyBase64: String): String { val keyBytes Base64.decode(privateKeyBase64, Base64.NO_WRAP) val privateKey KeyFactory.getInstance(ALGORITHM) .generatePrivate(PKCS8EncodedKeySpec(keyBytes)) val cipher Cipher.getInstance(TRANSFORMATION) cipher.init(Cipher.DECRYPT_MODE, privateKey) return String(cipher.doFinal(Base64.decode(cipherBase64, Base64.NO_WRAP))) } /** 私钥签名返回 Base64 签名 */ fun sign(data: String, privateKeyBase64: String): String { val keyBytes Base64.decode(privateKeyBase64, Base64.NO_WRAP) val privateKey KeyFactory.getInstance(ALGORITHM) .generatePrivate(PKCS8EncodedKeySpec(keyBytes)) val sig java.security.Signature.getInstance(SIGN_ALGORITHM) sig.initSign(privateKey) sig.update(data.toByteArray()) return Base64.encodeToString(sig.sign(), Base64.NO_WRAP) } /** 公钥验签 */ fun verify(data: String, signatureBase64: String, publicKeyBase64: String): Boolean { val keyBytes Base64.decode(publicKeyBase64, Base64.NO_WRAP) val publicKey KeyFactory.getInstance(ALGORITHM) .generatePublic(X509EncodedKeySpec(keyBytes)) val sig java.security.Signature.getInstance(SIGN_ALGORITHM) sig.initVerify(publicKey) sig.update(data.toByteArray()) return sig.verify(Base64.decode(signatureBase64, Base64.NO_WRAP)) } } // // MD5 / SHA 系列哈希 // object HashUtils { /** MD5返回 32 位小写十六进制 */ fun md5(input: String): String digest(MD5, input) /** SHA-1 */ fun sha1(input: String): String digest(SHA-1, input) /** SHA-256 */ fun sha256(input: String): String digest(SHA-256, input) /** SHA-512 */ fun sha512(input: String): String digest(SHA-512, input) private fun digest(algorithm: String, input: String): String { val md MessageDigest.getInstance(algorithm) return md.digest(input.toByteArray(Charsets.UTF_8)) .joinToString() { %02x.format(it) } } /** 对文件/二进制数据计算 MD5 */ fun md5Bytes(bytes: ByteArray): String { val md MessageDigest.getInstance(MD5) return md.digest(bytes).joinToString() { %02x.format(it) } } } // // HMAC带密钥的消息认证码 // object HMACUtils { /** HMAC-MD5 */ fun hmacMD5(data: String, key: String): String hmac(HmacMD5, data, key) /** HMAC-SHA256 */ fun hmacSHA256(data: String, key: String): String hmac(HmacSHA256, data, key) /** HMAC-SHA512 */ fun hmacSHA512(data: String, key: String): String hmac(HmacSHA512, data, key) private fun hmac(algorithm: String, data: String, key: String): String { val mac Mac.getInstance(algorithm) mac.init(SecretKeySpec(key.toByteArray(Charsets.UTF_8), algorithm)) return mac.doFinal(data.toByteArray(Charsets.UTF_8)) .joinToString() { %02x.format(it) } } } // // PBKDF2 密码哈希推荐替代 MD5 存储密码 // object PBKDF2Utils { private const val ALGORITHM PBKDF2WithHmacSHA256 private const val ITERATIONS 120_000 private const val KEY_LENGTH 256 // bits /** 生成随机盐 */ fun generateSalt(length: Int 16): ByteArray ByteArray(length).also { java.security.SecureRandom().nextBytes(it) } /** 对密码进行 PBKDF2 哈希返回 Base64 编码结果 */ fun hash(password: String, salt: ByteArray): String { val spec PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH) val factory SecretKeyFactory.getInstance(ALGORITHM) return Base64.encodeToString(factory.generateSecret(spec).encoded, Base64.NO_WRAP) } /** 验证密码将输入密码用同一盐再哈希后比较 */ fun verify(password: String, salt: ByteArray, storedHash: String): Boolean { return hash(password, salt) storedHash } } // // Base64 工具编码 / 解码 // object Base64Utils { fun encode(data: ByteArray): String Base64.encodeToString(data, Base64.NO_WRAP) fun encode(text: String): String encode(text.toByteArray(Charsets.UTF_8)) fun decode(base64: String): ByteArray Base64.decode(base64, Base64.NO_WRAP) fun decodeToString(base64: String): String String(decode(base64), Charsets.UTF_8) } // // 使用示例可删除 // fun main() { // ---- AES ---- val aesKey AESUtils.generateKey() val cipher AESUtils.encryptCBC(Hello Android!, aesKey) val plain AESUtils.decryptCBC(cipher, aesKey) println(AES-CBC 解密: $plain) // ---- RSA ---- val keyPair RSAUtils.generateKeyPair() val rsaCipher RSAUtils.encryptByPublicKey(Hello RSA, keyPair.publicKeyBase64) val rsaPlain RSAUtils.decryptByPrivateKey(rsaCipher, keyPair.privateKeyBase64) println(RSA 解密: $rsaPlain) val signature RSAUtils.sign(签名内容, keyPair.privateKeyBase64) println(RSA 验签: ${RSAUtils.verify(签名内容, signature, keyPair.publicKeyBase64)}) // ---- Hash ---- println(MD5: ${HashUtils.md5(password)}) println(SHA256: ${HashUtils.sha256(password)}) // ---- HMAC ---- println(HMAC-SHA256: ${HMACUtils.hmacSHA256(message, secret_key)}) // ---- PBKDF2 ---- val salt PBKDF2Utils.generateSalt() val hashed PBKDF2Utils.hash(my_password, salt) println(PBKDF2 验证: ${PBKDF2Utils.verify(my_password, salt, hashed)}) } ###拦截器 import okhttp3.* import java.io.IOException // 拦截器1请求前处理 class BeforeRequestInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val original chain.request() println(【请求前】原始 URL: ${original.url}) // 给请求加一些统一的东西Header、时间戳、UA等 val newRequest original.newBuilder() .addHeader(User-Agent, MyApp/1.0) .addHeader(X-Timestamp, System.currentTimeMillis().toString()) .build() println(【请求前】处理完成加了 Header: User-Agent, X-Timestamp) // 把改过的请求往下传交给下一个拦截器 return chain.proceed(newRequest) } } // 拦截器2响应后处理 class AfterResponseInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request chain.request() // 先让请求真正发出去或交给链上下一环 val response chain.proceed(request) println(【响应后】状态码: ${response.code}) println(【响应后】耗时统计、日志记录等逻辑可以写在这里) // 注意response.body 只能读一次这里演示要用 peekBody 或重新构造 val bodyString response.peekBody(2048).string() println(【响应后】响应体预览: ${bodyString.take(200)}) // 可以直接把原始 response 返回也可以构造新的 Response 对象再返回 return response } } // 真实请求 fun main() { val client OkHttpClient.Builder() .addInterceptor(BeforeRequestInterceptor()) // 先执行处理请求 .addInterceptor(AfterResponseInterceptor()) // 后执行处理响应 .build() val request Request.Builder() .url(https://httpbin.org/get) // 真实可访问的测试接口会原样返回请求信息 .get() .build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { println(请求失败: ${e.message}) } override fun onResponse(call: Call, response: Response) { response.use { println(最终拿到响应长度: ${it.body?.contentLength()}) } } }) Thread.sleep(3000) // 仅为了让 main 函数不提前退出实际项目不需要 }