长沙门户网站建设/成都网站seo费用
Android webview拦截H5的接口请求并返回处理好的数据
Android 可以通过 WebView
的 shouldInterceptRequest
方法拦截到 H5 中的网络请求。这是一个 WebViewClient
中的回调方法,允许开发者在 WebView 发起网络请求时对其进行处理和修改。
具体使用方法如下:
-
你需要创建一个自定义的
WebViewClient
,并重写shouldInterceptRequest
方法。 -
在该方法中,你可以拦截 WebView 发起的网络请求,并返回一个自定义的响应,或让请求继续。
-
该方法在 API 21 (Android 5.0) 及更高版本中引入了两个重载方法:
shouldInterceptRequest(WebView view, String url)
(API 11)shouldInterceptRequest(WebView view, WebResourceRequest request)
(API 21)
以下是代码示例:
// Kotlin 代码示例
webView.webViewClient = object : WebViewClient() {// 对于 API 21 及更高版本override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {val url = request.url.toString()// 这里你可以判断 URL,并根据需要拦截或修改请求if (url.contains("your_target_url")) {// 可以在这里做一些处理,例如替换请求或返回本地数据val inputStream = ... // 自定义输入流return WebResourceResponse("text/html", "UTF-8", inputStream)}// 不拦截,继续请求return super.shouldInterceptRequest(view, request)}// 对于 API 11 到 API 20 的设备override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {// 这里处理逻辑类似于上面的代码if (url.contains("your_target_url")) {// 自定义处理逻辑val inputStream = ... return WebResourceResponse("text/html", "UTF-8", inputStream)}return super.shouldInterceptRequest(view, url)}
}
在 shouldInterceptRequest
方法中,你可以返回一个 WebResourceResponse
对象,来改变或替换原始的网络请求,也可以通过默认实现让请求继续执行。
获取网络接口请求的数据(如 API 请求的响应),然后将其返回给 H5,
有以下几种方式可以考虑:
1. 拦截请求并手动发起请求
你可以通过 shouldInterceptRequest
方法拦截 WebView 的 API 请求,自己在 Java 或 Kotlin 中使用 HttpURLConnection
或 OkHttp
发起网络请求,处理完响应后,再将响应数据传递给 H5。
示例代码:
webView.webViewClient = object : WebViewClient() {override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {val url = request.url.toString()// 判断是否是需要拦截的接口请求if (url.contains("your_api_endpoint")) {// 通过 OkHttp 或 HttpURLConnection 发起请求val response = fetchApiData(url)// 将获取的响应内容传递给 H5view.post {view.evaluateJavascript("javascript:handleApiResponse('${response}')", null)}// 返回一个空响应或自定义内容return WebResourceResponse("application/json", "UTF-8", null)}return super.shouldInterceptRequest(view, request)}// 使用 OkHttp 发起网络请求(可以根据你的需求选择合适的网络库)private fun fetchApiData(url: String): String {// 简单 OkHttp 请求示例val client = OkHttpClient()val request = Request.Builder().url(url).build()client.newCall(request).execute().use { response ->return response.body?.string() ?: ""}}
}
在这个例子中,shouldInterceptRequest
会拦截指定的网络请求,然后用 OkHttp
发起请求,并将获取的响应数据通过 evaluateJavascript
方法传回到 WebView 中的 H5 页面。
2. 通过 WebView 和 H5 的 JavaScript 通信
另一种方式是通过 WebView 的 addJavascriptInterface
方法,将 Android 代码和 H5 进行通信。当 Android 发起请求后,可以通过接口将数据传递给 H5。
-
在 H5 中定义一个 JavaScript 函数,用于接收数据:
function handleApiResponse(response) {console.log("API Response: ", response);// 这里可以对响应进行处理,渲染到页面等
}
2. 在 Android 端:
webView.addJavascriptInterface(object {@JavascriptInterfacefun sendDataToH5(data: String) {// 发送数据到 H5webView.evaluateJavascript("javascript:handleApiResponse('$data')", null)}
}, "AndroidInterface")webView.webViewClient = object : WebViewClient() {override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {val url = request.url.toString()if (url.contains("your_api_endpoint")) {val response = fetchApiData(url)// 通过 JavaScript 接口传递数据到 H5view.post {view.evaluateJavascript("javascript:AndroidInterface.sendDataToH5('${response}')", null)}return WebResourceResponse("application/json", "UTF-8", null)}return super.shouldInterceptRequest(view, request)}
}
这种需要考虑到H5 发过来的网络接口请求类型吗?post 还是 get
是的,在使用 shouldInterceptRequest
拦截 H5 发过来的网络请求时,需要考虑请求的类型(GET 或 POST)。这是因为 GET 和 POST 请求的处理方式不同,尤其是 POST 请求,它带有请求体(body)数据,而 GET 请求通常只包含 URL 参数。
shouldInterceptRequest
可以帮助你拦截请求,但对于 POST 请求的处理,需要特别注意提取和使用请求体。
如何区分 GET 和 POST 请求?
在 API 21 及更高版本中,shouldInterceptRequest
方法中的 WebResourceRequest
对象包含了更多信息,可以通过它的 getMethod()
方法来区分请求类型。
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest
): WebResourceResponse? {val url = request.url.toString()val method = request.method // 获取请求方法,如 GET 或 POST// 根据请求类型处理if (method == "POST") {// 获取 POST 请求的 body(在 Android 的 WebView 中,直接获取 POST body 是不支持的,除非使用特定工具)// 自定义逻辑处理 POST 请求} else if (method == "GET") {// 处理 GET 请求}return super.shouldInterceptRequest(view, request)
}
处理 POST 请求
Android 的 shouldInterceptRequest
本身不直接提供获取 POST 请求体的功能。不过你可以使用其他方式来处理,例如通过在 JS 中提前将请求体通过某种方式传递给 Android。
方法 1:使用 evaluateJavascript
传递 POST 请求数据
你可以让 H5 页面在发出 POST 请求前,通过 JavaScript 提前将 POST 请求的数据发送到 WebView。然后 Android 端可以拦截并处理这些数据。
-
在 H5 中拦截和传递 POST 请求数据:
function interceptAndSendPostData(url, data) {// 调用 Android 接口,将数据传递给 WebViewAndroidInterface.sendPostData(url, JSON.stringify(data));// 继续发起 POST 请求fetch(url, {method: "POST",body: JSON.stringify(data),headers: {"Content-Type": "application/json"}}).then(response => response.json()).then(data => console.log(data)); }
-
在 Android 中接收 POST 数据:
webView.addJavascriptInterface(object {@JavascriptInterfacefun sendPostData(url: String, data: String) {// 这里可以处理传递过来的 POST 请求数据Log.d("WebView", "POST 请求 URL: $url, 数据: $data")} }, "AndroidInterface")
方法 2:通过自定义网络层发送 POST 请求
另一种方式是在 shouldInterceptRequest
中拦截 POST 请求后,手动发起 HTTP 请求,处理请求体和响应数据。虽然 shouldInterceptRequest
本身不直接提供请求体,但你可以在 H5 页面中通过 JavaScript 提前将 POST 请求体传递给 Android,或者通过其他网络拦截方式处理(例如使用 OkHttp 的拦截器)。
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest
): WebResourceResponse? {val url = request.url.toString()val method = request.method // 获取请求方法,如 GET 或 POSTif (method == "POST") {// 自定义发起 HTTP 请求,处理 POST 请求体和响应val response = performCustomHttpPost(url, request)return WebResourceResponse("application/json", "UTF-8", response)}return super.shouldInterceptRequest(view, request)
}fun performCustomHttpPost(url: String, request: WebResourceRequest): InputStream {// 使用 OkHttp 或 HttpURLConnection 发送自定义 POST 请求val client = OkHttpClient()val requestBody = ... // 构建请求体val request = Request.Builder().url(url).post(requestBody).build()val response = client.newCall(request).execute()return response.body?.byteStream() ?: ByteArrayInputStream(ByteArray(0))
}
小结
- GET 请求:你可以直接通过 URL 和请求头信息来拦截和处理。
- POST 请求:需要特别处理请求体数据。你可以通过 JavaScript 提前将 POST 请求数据传递给 WebView,或通过手动发起 HTTP 请求处理 POST 请求及其响应。
shouldInterceptRequest 能判断出来网络请求的类型吗?比如script xhr 等
shouldInterceptRequest
本身并不能直接判断网络请求的具体类型(如 script
、xhr
等),因为它没有提供一个字段明确表明请求是某种类型的资源(如 JavaScript 文件、XHR 请求等)。不过,你可以通过请求的 URL 和 请求头信息 来推断请求的类型。
在 API 21 及以上的 Android 版本中,WebResourceRequest
对象提供了丰富的信息,包括请求的 URL、请求方法(GET、POST 等)、请求头等,可以根据这些信息推断请求类型。
如何通过 URL 和请求头判断请求类型?
-
通过 URL 后缀:
- 如果请求的 URL 以
.js
结尾,通常可以认为这是一个script
请求。 - 如果 URL 中包含
/api/
或类似的标识符,可能是xhr
请求。 - CSS 通常以
.css
结尾,图片文件以.jpg
、.png
、.gif
结尾等。
- 如果请求的 URL 以
-
通过请求头: 你可以通过请求的头部来推断请求的类型,例如
Accept
头部通常指示客户端期望接收到的数据类型。Accept: application/json
常用于xhr
请求。Accept: text/css
表示请求 CSS 文件。Accept: application/javascript
或Accept: text/javascript
用于 JavaScript 文件请求。
代码示例:如何通过 URL 和请求头推断请求类型
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest
): WebResourceResponse? {val url = request.url.toString()val headers = request.requestHeadersval acceptHeader = headers["Accept"] // 获取 Accept 头// 判断是否为脚本请求 (script)if (url.endsWith(".js") || acceptHeader?.contains("application/javascript") == true) {Log.d("WebView", "拦截到脚本请求: $url")// 在此可以拦截或修改脚本请求}// 判断是否为 XHR 请求 (通过 URL 或 Accept 头判断)if (url.contains("/api/") || acceptHeader?.contains("application/json") == true) {Log.d("WebView", "拦截到 XHR 请求: $url")// 在此可以拦截或修改 XHR 请求}// 判断是否为 CSS 请求if (url.endsWith(".css") || acceptHeader?.contains("text/css") == true) {Log.d("WebView", "拦截到 CSS 请求: $url")// 在此可以拦截或修改 CSS 请求}// 其他资源类型的请求Log.d("WebView", "其他类型的请求: $url")return super.shouldInterceptRequest(view, request)
}
常见资源类型的判断方式
- JavaScript 文件请求 (
script
):- 通过 URL 判断:
url.endsWith(".js")
- 通过
Accept
头判断:application/javascript
或text/javascript
- 通过 URL 判断:
- XHR 请求:
- 通过 URL 规则判断:如果 URL 中包含
/api/
、/ajax/
或其他常见的 API 路径。 - 通过
Accept
头判断:application/json
- 通过 URL 规则判断:如果 URL 中包含
- CSS 文件请求:
- 通过 URL 判断:
url.endsWith(".css")
- 通过
Accept
头判断:text/css
- 通过 URL 判断:
- 图片文件请求:
- 通过 URL 判断:
url.endsWith(".jpg")
、.png
、.gif
等 - 通过
Accept
头判断:image/*
- 通过 URL 判断:
- HTML 页面请求:
- 通过
Accept
头判断:text/html
- 通过
小结
虽然 shouldInterceptRequest
没有直接提供资源类型的字段,但你可以通过 URL 的格式和请求头(特别是 Accept
头)来推断请求的类型,从而拦截特定的资源请求。
script xhr font png preflight 分别是什么,应该怎么判断呢?都可以通过 val acceptHeader = headers["Accept"] 来进行判断吗?
Accept
头在 HTTP 请求中指示客户端希望接收的响应数据类型,它确实能在一些情况下帮助我们判断请求的资源类型。但并不是所有类型的请求都会明确使用 Accept
头。因此,我们需要结合 URL 和 请求头 的其他信息(如 Content-Type
、Access-Control-Request-Method
等)来进行判断。
1. Script(JavaScript 请求)
JavaScript 请求是用来加载 .js
文件的资源请求。
判断依据:
- URL 后缀:通常
.js
文件后缀。 Accept
头:application/javascript
或text/javascript
。
if (url.endsWith(".js") || acceptHeader?.contains("application/javascript") == true || acceptHeader?.contains("text/javascript") == true) {Log.d("WebView", "拦截到 JavaScript 请求: $url")
}
2. XHR 请求(XMLHttpRequest / Fetch 请求)
XHR 请求通常用于 AJAX 请求或使用 Fetch API
的异步网络请求。
判断依据:
- URL 规则:API 请求通常有特定路径,例如
/api/
、/ajax/
等。 Accept
头:application/json
(如果返回 JSON 数据)。- 请求头:XHR 请求会带有
X-Requested-With: XMLHttpRequest
头部(但不是所有情况都有此头部)。
if (url.contains("/api/") || acceptHeader?.contains("application/json") == true || headers["X-Requested-With"] == "XMLHttpRequest") {Log.d("WebView", "拦截到 XHR 请求: $url")
}
3. Font 请求(字体文件请求)
字体文件通常以 .woff
、.woff2
、.ttf
、.otf
等后缀结尾。
判断依据:
- URL 后缀:
.woff
、.woff2
、.ttf
、.otf
。 Accept
头:font/*
或application/font-woff
。
if (url.endsWith(".woff") || url.endsWith(".woff2") || url.endsWith(".ttf") || url.endsWith(".otf") || acceptHeader?.contains("font/") == true) {Log.d("WebView", "拦截到字体文件请求: $url")
}
4. PNG 请求(图片请求)
图片请求通常包括 .png
、.jpg
、.gif
等格式。
判断依据:
- URL 后缀:图片文件通常以
.png
、.jpg
、.jpeg
、.gif
结尾。 Accept
头:image/*
。
if (url.endsWith(".png") || url.endsWith(".jpg") || url.endsWith(".jpeg") || url.endsWith(".gif") || acceptHeader?.contains("image/") == true) {Log.d("WebView", "拦截到图片请求: $url")
}
5. Preflight 请求
Preflight 请求是 CORS 请求的一部分,通常在跨域 POST、PUT、DELETE 请求前发送,以确定服务器是否允许该请求。Preflight 请求使用 OPTIONS
方法发起。
判断依据:
- HTTP 方法:
OPTIONS
(Preflight 请求是OPTIONS
方法的请求)。 - 请求头:包含
Access-Control-Request-Method
和Access-Control-Request-Headers
。
if (request.method == "OPTIONS" && headers.containsKey("Access-Control-Request-Method")) {Log.d("WebView", "拦截到 Preflight 请求: $url")
}
结合 URL 和 Accept
头进行判断
总结不同请求类型的判断依据:
请求类型 | URL 后缀 | Accept 头 | 其他请求头信息 |
---|---|---|---|
Script (JavaScript) | .js | application/javascript , text/javascript | |
XHR (AJAX) | /api/ , /ajax/ | application/json | X-Requested-With: XMLHttpRequest |
Font (字体) | .woff , .woff2 , .ttf , .otf | font/* , application/font-woff | |
Image (图片) | .png , .jpg , .jpeg , .gif | image/* | |
Preflight (CORS) | OPTIONS 方法,Access-Control-Request-Method |
小结
Accept
头可以帮助判断请求类型,但并不是所有请求都明确使用它。- 根据 URL 后缀、请求方法、其他请求头(如
X-Requested-With
、Access-Control-Request-Method
)结合判断能更准确识别不同类型的请求。
返回的响应不符合预期的格式,怎么处理
出现 AxiosError: Network Error, Code: ERR_NETWORK
错误,通常是因为 WebView 在处理拦截的网络请求时,返回的响应不符合预期的格式,或者某些必要的头信息缺失。这里有几个常见的原因及解决办法:
问题可能的原因:
-
响应流的格式或处理错误: 你正在返回
response.body()?.byteStream()
,但是你还需要确保整个WebResourceResponse
对象是正确配置的,尤其是内容类型、编码格式以及响应头信息。任何一项出错都可能导致 H5(例如通过 Axios)认为网络请求失败。 -
响应头缺失或不完整:
WebResourceResponse
需要提供一些关键的响应头,比如Content-Type
和Content-Length
,这些头在网络请求处理中是必需的。H5 请求的 Axios 需要明确知道响应的长度和类型,否则会认为响应无效。 -
返回的流不完整或被提前关闭: 如果返回的流有问题,比如它被提前关闭或者有其他异常情况,可能导致 Axios 在处理时报错。
如何正确返回自定义响应
确保你使用 WebResourceResponse
构建响应时,包括了所有必要的头信息和流数据。
修改代码示例
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest
): WebResourceResponse? {val url = request.url.toString()if (url.contains("your_api_endpoint")) {// 发起网络请求获取数据val response = fetchApiData(url)// 处理返回的响应流val byteStream = response.body?.byteStream() ?: ByteArrayInputStream(ByteArray(0))val contentType = response.header("Content-Type", "application/json") // 设置默认内容类型val contentLength = response.header("Content-Length", "-1").toLong() // 设置内容长度// 构建 WebResourceResponse 并返回给 WebViewreturn WebResourceResponse(contentType, // 内容类型"utf-8", // 编码格式200, // HTTP 状态码"OK", // 状态描述mapOf( // 响应头"Access-Control-Allow-Origin" to "*","Content-Length" to contentLength.toString()),byteStream // 响应内容的输入流)}return super.shouldInterceptRequest(view, request)
}// 使用 OkHttp 发起网络请求
private fun fetchApiData(url: String): Response {val client = OkHttpClient()val request = Request.Builder().url(url).build()return client.newCall(request).execute() // 直接返回 Response 对象
}
关键修改点:
-
正确设置内容类型和编码:通过
response.header("Content-Type")
获取原始响应的Content-Type
,并传递给WebResourceResponse
。通常是application/json
。 -
设置
Content-Length
:通过response.header("Content-Length")
获取响应内容的长度,并将其传递给 WebView。如果缺少Content-Length
,某些 H5 请求库(如 Axios)可能会报错。 -
返回有效的响应流:你需要确保
response.body()?.byteStream()
是有效的。如果网络请求失败或流为空,你可以返回一个空的ByteArrayInputStream()
。 -
设置状态码和状态描述:如果请求成功,确保返回
200 OK
,否则应根据具体情况返回相应的状态码和描述。
检查点
-
确保响应流有效:确保
response.body()?.byteStream()
真的有数据,否则 H5 端会认为是无效的响应。你可以通过调试查看响应流的状态。 -
正确设置头信息:特别是
Content-Type
和Content-Length
,它们是网络请求处理的关键。Axios 依赖这些头信息来解析响应。 -
错误处理:如果在网络请求过程中发生错误,应返回合适的错误响应,比如
404 Not Found
或500 Internal Server Error
,而不是直接返回空的响应流。
调试建议
- 通过日志调试输出 OkHttp 请求的状态,确保
fetchApiData
函数返回的Response
对象中包含有效的数据。 - 在 Axios 端检查返回的响应头,确保
Content-Type
、Content-Length
等信息是正确的。
shouldInterceptRequest 拦截POST请求的时候,如何获取POST 请求的 body 数据?
在 Android 的 WebViewClient
中通过 shouldInterceptRequest
拦截 POST 请求并构建自定义的 HTTP 请求时,首先需要手动构建请求体(如从 WebResourceRequest
中获取必要的请求信息),然后使用 OkHttp
或 HttpURLConnection
来发送这个 POST 请求。
WebResourceRequest
不直接提供 POST 请求体,因此要获取并手动构建 POST 请求体。这可以通过 requestHeaders
来构建,或在前端(H5)发送时提前传递 POST 数据。
处理 POST 请求并构建请求体的完整示例:
override fun shouldInterceptRequest(view: WebView,request: WebResourceRequest
): WebResourceResponse? {val url = request.url.toString()val method = request.methodif (method == "POST") {Log.d("WebView", "拦截到 POST 请求: $url")// 自定义处理 POST 请求,构建请求体并发送val responseStream = performCustomHttpPost(url, request)// 返回自定义的 WebResourceResponsereturn WebResourceResponse("application/json", // 假设返回的是 JSON 响应"UTF-8",200, // HTTP 状态码"OK", // HTTP 状态描述mapOf("Access-Control-Allow-Origin" to "*"), // 响应头responseStream // 响应数据的输入流)}return super.shouldInterceptRequest(view, request)
}// 自定义处理 POST 请求的逻辑
fun performCustomHttpPost(url: String, request: WebResourceRequest): InputStream {// 构建 POST 请求体(假设 H5 端发送的 POST 数据是 JSON 格式)val postData = getPostData(request) // 假设这里可以提取请求体数据// 日志记录请求体数据Log.d("WebView", "POST 请求数据: $postData")// 使用 OkHttp 发送自定义的 POST 请求val client = OkHttpClient()val requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), // 假设请求体是 JSON 数据postData ?: "" // POST 请求的数据)val customRequest = Request.Builder().url(url).post(requestBody).build()// 发起请求并返回响应流val response = client.newCall(customRequest).execute()Log.d("WebView", "HTTP 响应码: ${response.code()}") // 日志记录响应状态码return response.body?.byteStream() ?: ByteArrayInputStream(ByteArray(0))
}// 获取 POST 数据(需要通过前端传递或其他方式获取)
fun getPostData(request: WebResourceRequest): String? {// WebView 无法直接获取 POST body 数据,需要前端配合通过 evaluateJavascript 或其他方式传递// 假设我们从 requestHeaders 中获取部分数据(实际可以根据你的需求进行修改)val contentType = request.requestHeaders["Content-Type"]Log.d("WebView", "Content-Type: $contentType")// 这里返回模拟的 POST 数据,实际情况下需要处理真实的请求体return "{ \"key\": \"value\" }"
}
关键点:
获取请求体数据:Android WebView 本身不提供获取 POST 请求体的直接方式,需要通过前端协作(如 evaluateJavascript)来传递请求体,或者自行处理模拟请求体。手动构建 POST 请求体:使用 OkHttp 的 RequestBody.create() 方法手动构建 POST 请求体。记录日志:通过 Log.d() 记录拦截的 URL 和请求体数据,便于调试。
记录 HTTP 响应状态码,查看请求是否成功。
处理异常情况:如果响应体为空,返回一个空的 ByteArrayInputStream(),以确保 WebView 不会崩溃。关于获取真实的 POST 请求体
Android 的 WebView 没有内置机制直接获取 POST 请求体,因此需要通过 JavaScript 与 Android 通信,在 H5 端主动将 POST 数据发送给 WebView。例如:
// 在 H5 端获取 POST 请求体并传递给 Android
function sendPostDataToAndroid(data) {if (window.AndroidInterface) {window.AndroidInterface.sendPostData(JSON.stringify(data));}
}
然后在 Android 端通过 addJavascriptInterface
接收数据:
@JavascriptInterface
fun sendPostData(data: String) {// 处理从 H5 传递过来的 POST 数据Log.d("WebView", "收到的 POST 数据: $data")
}
最后
其实获取post请求体参数内容上述的方法可以尝试一下,当然,还有一种更简单的取巧的方法,如果H5 POST请求数量不是很多的话,可以和H5沟通好,直接把请求数据放在请求的url中,中间通过特定字符@隔开,然后我们拿到后进行处理,
// 判断是否为 XHR 请求 (通过 URL 或 Accept 头判断)if ((url.contains("/api/") || acceptHeader?.contains("application/json") == true ||headers["X-Requested-With"] == "XMLHttpRequest") && !url.endsWith("html")) {LogUtils.i( "拦截到 XHR 请求: $url")// 在此可以拦截或修改 XHR 请求var respone: Response? = nullif(method == "POST"){val params = url.split("@")val test = params[0] // 获取 POST 请求的 body 数据val postData = URLDecoder.decode(params[1], StandardCharsets.UTF_8.toString())LogUtils.i("postData = $postData")respone = fetchApiData2(test,method,postData)}else if(method == "GET"){respone = fetchApiData(url,method,null)}val byteStream = respone?.body()?.byteStream() ?: ByteArrayInputStream(ByteArray(0))val contentType = respone?.header("Content-Type", "application/json") // 设置默认内容类型val contentLength = respone?.header("Content-Length", "-1")?.toLong() // 设置内容长度LogUtils.i("fetchApiData respone = ${respone.toString()}")return WebResourceResponse(contentType, // 内容类型"utf-8", // 编码格式200, // HTTP 状态码"OK", // 状态描述mapOf( // 响应头"Access-Control-Allow-Origin" to "*","Content-Length" to contentLength.toString()),byteStream // 响应内容的输入流)// return WebResourceResponse("application/json", "utf-8",respone)}
private fun fetchApiData2(url: String, method: String, postData: String?): Response{LogUtils.i("fetchApiData2 = $url + $method + $postData")val client = UnsafeOkHttpClient.unsafeOkHttpClient.build()val requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), // 假设请求体是 JSON 数据postData ?: "" // POST 请求的数据)val requestBuilder = Request.Builder().url(url).post(requestBody).build()return client.newCall(requestBuilder).execute()}
// 根据请求类型进行处理private fun fetchApiData(url: String, method: String, postData: Map<String, String>?): Response {LogUtils.i("fetchApiData = $url + $method + $postData")val client = UnsafeOkHttpClient.unsafeOkHttpClient.build()val requestBuilder = Request.Builder().url(url)// 根据请求类型构建请求if (method == "POST" && postData != null) {val formBody = FormBody.Builder()postData.forEach { (key, value) -> formBody.add(key, value) }requestBuilder.post(formBody.build())}val request = requestBuilder.build()return client.newCall(request).execute() // 直接返回 Response 对象
}
相关文章:

Android webview拦截H5的接口请求并返回处理好的数据
Android webview拦截H5的接口请求并返回处理好的数据 Android 可以通过 WebView 的 shouldInterceptRequest 方法拦截到 H5 中的网络请求。这是一个 WebViewClient 中的回调方法,允许开发者在 WebView 发起网络请求时对其进行处理和修改。 具体使用方法如下&#…...

vue echarts tooltip使用动态模板
先上代码 tooltip: {// 这里是车辆iconshow: true,// trigger: "item",// backgroundColor: "transparent",appendToBody: true,textStyle: {color: "#ffffff" //设置文字颜色},formatter: (params) > {return formatHtml(params.data)},}, …...

網路本地連接沒有有效的IP配置:原因與解決方法
網路本地連接顯示“沒有有效的IP配置”。這通常意味著你的電腦無法從路由器或其他網路設備獲取有效的IP地址,從而導致無法上網。本文將從原因和解決方法兩個方面,詳細解析這個問題。 一、問題的原因 路由器或數據機問題: 路由器或數據機出…...

如何使用ssm实现基于web的学生就业管理系统的设计与实现+vue
TOC ssm726基于web的学生就业管理系统的设计与实现vue 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现,改变了几千年以来人们的生活,不仅仅是生活物资的丰富,还有精神层次的丰富。在互联网诞生之前,地域位置往往是人们思想上…...

TCP三次握手四次挥手详解
TCP三次握手建立连接的过程: 一次握手:客户端发送带有 SYN(seqx)标志的数据包到服务端,然后客户端进入 SYN_SEND 状态,等待服务端的确认。二次握手:服务端收到 SYN 包后,发送带有 S…...

了解 如何使用同快充充电器给不同设备快速充电
在这科技发展迅速的时代,快充技术已经走进了我们生活,不得不说有了快充技术的对比,传统的充电模式已经满足不了人们对充电速度的要求。就比如用华为输出100 W快充充电器为手机充电大概需要23分钟充满100%电量,而传统的充电器则需要…...

AGI interior designer丨OPENAIGC开发者大赛高校组AI创作力奖
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…...

Centos安装docker(linux安装docker)——超详细小白可操作手把手教程,包好用!!!
🧸本篇博客重在讲解Centos安装docker,经博主多次在不同服务器上测试,极其的稳定,尤其是阿里的服务器,一路复制命令畅通无阻 📜后续会退出ububtu安装docker教程,敬请期待 📜作者首页&…...

QT day01
自定义实现登录界面: #include "widget.h" #include "ui_widget.h" #include<QPushButton> #include<QLineEdit> #include<QLabel>Widget::Widget(QWidget *parent) //定义有参构造函数: QWidget(parent), ui(new Ui::Widge…...

如何从飞机、电报中提取数据
电报,通常简称TG,是一个跨平台的即时通讯软件。客户端是开源的,而服务器是专有的。用户可以交换加密的、自毁的信息(类似于“阅读后烧伤”),并共享各种文件,包括照片和视频。它的安全性很高&…...

【算法篇】二叉树类(2)(笔记)
目录 一、Leetcode 题目 1. 左叶子之和 (1)迭代法 (2)递归法 2. 找树左下角的值 (1)广度优先算法 (2)递归法 3. 路径总和 (1)递归法 (2…...

Flask学习之项目搭建
一、项目基本结构 1、 exts.py 存在的目的:在Python中,如果两个或更多模块(文件)相互导入对方,就会形成导入循环。例如,模块A导入了模块B,同时模块B又导入了模块A,这就会导致导入循环。 比如在这个项目中…...

**CentOS7安装Maven**
CentOS7安装Maven 首先先解压压缩包apache-maven-3.9.9-bin.tar.gz tar -xvf apache-maven-3.9.9-bin.tar.gz解压完毕后配置环境变量 vim /etc/profile在环境变量配置文件中加入这句话 #Maven export MAVEN_HOME/opt/soft/maven362 //换成自己的路径 export PATH$PATH:$JAVA…...

(undone) MIT6.824 Lecture1 笔记
参考1MIT课程视频:https://www.bilibili.com/video/BV16f4y1z7kn/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 参考2某大佬笔记:https://ashiamd.github.io/docsify-notes/#/study/%E5%88%86%E5%B8%83%…...

小白投资理财 - 开篇
小白投资理财 - 开篇 第一健身第二提升工作技能第三理财自律和规划 我认为的人生三件大事值得投资,一是强身健体,有个好身体;二是提升工作技能,不断学习工作领域里的新知识;三是投资理财,确保资产不贬值。 …...

高中还来得及选择信息学奥赛赛道吗?
随着信息学奥赛(NOI)在升学中的重要性日益凸显,越来越多的学生和家长将其视为进入顶尖高校的一个重要途径。然而,很多学生可能直到高中阶段才意识到信息学奥赛的重要性,或者才开始对编程产生兴趣。于是问题出现了&…...

01_OpenCV图片读取与展示
import cv2 img cv2.imread(夕阳.jpg, 1) #cv2.imshow(image, img) #此行只能命令行处py文件执行,会弹出一个视频窗口 #cv2.waitKey (0)以下会在jupyter Lab控件中显示读取的图像 #bgr8转jpeg格式 import enum import cv2def bgr8_to_jpeg(value, quality75):ret…...

C语言中的输入控制重要基础
在C语言编程中,处理输入数据是一个常见的任务。根据不同的情况,我们可以采用不同的输入控制方法。本文将介绍三类输入控制方式,分别是已知数据组数的输入、以特定符号结束的输入,以及以EOF结束的输入。 1. 已知数据组数的输入 在…...

Vue 学习
使用 vue 创建一个项目 检查是否已经安装了 npm 和 node npm --version node --version 使用 npm 安装 vue npm install -g vue/cli 检查 vue 工具是否安装成功 vue --version 使用 vue 工具创建一个名为 vue-router-syntax 的项目 这是命令行的创建方式 vue create vu…...

Redis集群的两种方式
1.Redis集群 1.1 搭建主从集群 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写的分离。一般情况下,主节点负责写操作,从节点负责读操作。而从节点如何得知数据呢ÿ…...

QT--基础
将默认提供的程序都注释上意义 0101.pro QT core gui #QT表示要引入的类库 core:核心库 gui:图形化界面库 #如果要使用其他库类中的相关函数,则需要加对应的库类后,才能使用 greaterThan(QT_MAJOR_VERSION, 4): QT wid…...

一、前后端分离及drf的概念
1.1什么是前后端分离 程序角度 前后端不分离:一个程序(如django),接收请求处理HTML模版用户返回 前后端分离:两个程序 --前端:vue.js/react.js/angular.js --后端:Django drf(django rest framework) 2.专业角度 --…...

AI垃圾溢出识别摄像机
随着城市化进程的加快,垃圾处理成为城市管理中的一项重要工作。然而,垃圾桶溢出现象经常发生,给城市环境卫生和市民生活带来不便。为了解决这一问题,AI垃圾溢出识别摄像机 应运而生,利用人工智能技术,实现对…...

【抽代复习笔记】29-群(二十三):生成子群的两道例题及子群陪集的定义
例1:取S3的子集S {(12),(123)},S的生成子群包含哪些元?一个群的两个不同的子集会不会生成相同的子群? 解:(1)S的生成子群就是S3。证明[有不理解之处可以回头看看第27篇笔记中生成子群的定…...

安全防护装备检测系统源码分享
安全防护装备检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…...

easyexcel常见问题分析
文章目录 一、读取数字多了很多小数位的精度问题 一、读取数字多了很多小数位的精度问题 浮点型转成BigDecimal的时候会出现精度问题,例如 这儿设置的实体类对象类型是String,默认用到的是StringNumberConverter转换器 2.1.4 版本 public class Strin…...

精通推荐算法31:行为序列建模之ETA — 基于SimHash实现检索索引在线化
1 行为序列建模总体架构 2 SIM模型的不足和为什么需要ETA模型 SIM实现了长周期行为序列的在线建模,其GSU检索单元居功至伟。但不论Hard-search还是Soft-search,都存在如下不足: GSU检索的目标与主模型不一致。Hard-search通过类目属性来筛选…...

Python知识点:如何使用Python进行卫星数据分析
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 如何使用Python进行卫星数据分析 卫星数据分析是地球观测领域的一项关键技术&a…...

Python实现Phong着色模型算法
目录 使用Python实现Phong着色模型算法引言Phong着色模型的基本原理1. 模型组成2. 公式 Phong着色模型的Python实现1. 向量类的实现2. 光源类的实现3. 材质类的实现4. Phong着色器类的实现 整体实现总结 使用Python实现Phong着色模型算法 引言 在计算机图形学中,光…...

异步框架 fastapi -- 连接mysql数据库
文章目录 docker部署mysqlfastapi连接mysql docker部署mysql 拉取mysql镜像 # 查看docker 服务状态 systemctl status docker systemctl start docker # 设置 开机启动 systemctl enable docker# 拉取mysql 镜像 docker search mysql:latest # 不指定版本时,默认…...