如何在Java/Android应用中实现SOAP请求并校验Wifi设备响应?
实现Java/Android本地WiFi设备SOAP请求与响应校验
下面提供两种实用方案,无需依赖老旧库,直接适配现代Java/Android开发需求:
方案1:原生HttpURLConnection(无额外依赖)
适合不想引入第三方库的场景,Android原生支持。
1. 准备SOAP请求体
把你在SoapUI中使用的SOAP信封完整复制为字符串,注意保留所有命名空间和参数:
private static final String SOAP_REQUEST = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:dev=\"http://your-device-namespace\">\n" + " <soapenv:Header/>\n" + " <soapenv:Body>\n" + " <dev:YourTargetMethod>\n" + " <!-- 填入SoapUI中使用的请求参数 -->\n" + " </dev:YourTargetMethod>\n" + " </soapenv:Body>\n" + "</soapenv:Envelope>";
2. 发送请求并校验响应
Android中必须在异步线程执行网络操作,以下是Kotlin协程(推荐)和Java AsyncTask的示例:
Kotlin 协程示例
import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.BufferedReader import java.io.OutputStreamWriter import java.net.HttpURLConnection import java.net.URL class MainActivity : AppCompatActivity() { private val DEVICE_SOAP_URL = "http://192.168.1.100:8080/soap-endpoint" // 替换为你的设备地址 private val SOAP_ACTION = "http://your-device-namespace/YourTargetMethod" // 替换为SoapUI中的SOAPAction private val TARGET_VERSION_STRING = "apiVersion>1.1.4<" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 启动异步请求 GlobalScope.launch(Dispatchers.Main) { val soapResponse = sendSoapRequest() val isVersionValid = soapResponse.contains(TARGET_VERSION_STRING) // 根据校验结果更新UI或执行后续逻辑 when(isVersionValid) { true -> { /* 版本符合要求 */ } false -> { /* 版本不符或请求失败 */ } } } } private suspend fun sendSoapRequest(): String = withContext(Dispatchers.IO) { var connection: HttpURLConnection? = null return@withContext try { val url = URL(DEVICE_SOAP_URL) connection = url.openConnection() as HttpURLConnection // 设置请求头 connection.requestMethod = "POST" connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8") connection.setRequestProperty("SOAPAction", SOAP_ACTION) // 允许写入请求体 connection.doOutput = true // 发送SOAP请求 OutputStreamWriter(connection.outputStream).use { writer -> writer.write(SOAP_REQUEST) writer.flush() } // 读取响应内容 val responseBuilder = StringBuilder() BufferedReader(java.io.InputStreamReader(connection.inputStream)).use { reader -> var line: String? while (reader.readLine().also { line = it } != null) { responseBuilder.append(line) } } responseBuilder.toString() } catch (e: Exception) { e.printStackTrace() "" } finally { connection?.disconnect() } } }
Java AsyncTask示例
import android.os.AsyncTask; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import java.io.BufferedReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public class MainActivity extends AppCompatActivity { private static final String DEVICE_SOAP_URL = "http://192.168.1.100:8080/soap-endpoint"; private static final String SOAP_REQUEST = "<soapenv:Envelope ...>...</soapenv:Envelope>"; // 替换为你的SOAP请求 private static final String SOAP_ACTION = "http://your-device-namespace/YourTargetMethod"; private static final String TARGET_VERSION_STRING = "apiVersion>1.1.4<"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new SoapRequestTask().execute(); } private class SoapRequestTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { HttpURLConnection connection = null; try { URL url = new URL(DEVICE_SOAP_URL); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); connection.setRequestProperty("SOAPAction", SOAP_ACTION); connection.setDoOutput(true); // 发送请求体 OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); writer.write(SOAP_REQUEST); writer.flush(); writer.close(); // 读取响应 BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); return response.toString(); } catch (Exception e) { e.printStackTrace(); return ""; } finally { if (connection != null) { connection.disconnect(); } } } @Override protected void onPostExecute(String response) { super.onPostExecute(response); boolean isVersionValid = response.contains(TARGET_VERSION_STRING); // 处理校验结果 } } }
方案2:OkHttp(简洁高效)
OkHttp是现代Android开发常用的网络库,代码更简洁,处理异常更方便。
1. 添加依赖
在模块级build.gradle中添加:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
2. 发送请求并校验
import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody class MainActivity : AppCompatActivity() { private val DEVICE_SOAP_URL = "http://192.168.1.100:8080/soap-endpoint" private val SOAP_REQUEST = "<soapenv:Envelope ...>...</soapenv:Envelope>" // 替换为你的SOAP请求 private val SOAP_ACTION = "http://your-device-namespace/YourTargetMethod" private val TARGET_VERSION_STRING = "apiVersion>1.1.4<" private val okHttpClient = OkHttpClient() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) GlobalScope.launch(Dispatchers.Main) { val soapResponse = sendSoapRequest() val isVersionValid = soapResponse.contains(TARGET_VERSION_STRING) // 处理校验结果 } } private suspend fun sendSoapRequest(): String = withContext(Dispatchers.IO) { val xmlMediaType = "text/xml;charset=utf-8".toMediaType() val requestBody = SOAP_REQUEST.toRequestBody(xmlMediaType) val request = Request.Builder() .url(DEVICE_SOAP_URL) .post(requestBody) .addHeader("Content-Type", "text/xml;charset=utf-8") .addHeader("SOAPAction", SOAP_ACTION) .build() return@withContext try { okHttpClient.newCall(request).execute().use { response -> if (!response.isSuccessful) throw RuntimeException("Request failed: ${response.code}") response.body?.string() ?: "" } } catch (e: Exception) { e.printStackTrace() "" } } }
进阶:精准XML解析校验
如果担心字符串匹配的误差(比如响应中存在类似字符串),可以用Android原生的XmlPullParser解析响应,精准获取apiVersion字段:
private fun parseApiVersion(soapResponse: String): String? { val parser = XmlPullParserFactory.newInstance().newPullParser() parser.setInput(soapResponse.reader()) var eventType = parser.eventType while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG && parser.name == "apiVersion") { eventType = parser.next() return parser.text } eventType = parser.next() } return null }
使用时:
val apiVersion = parseApiVersion(soapResponse) val isVersionValid = apiVersion == "1.1.4"
必加配置
- 在
AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
- 确保设备与手机处于同一WiFi网络,使用设备的局域网IP和端口访问。
内容的提问来源于stack exchange,提问作者Pierre Tremblay
相关产品推荐
相关产品推荐

