java.net.UnknownServiceException:网络安全策略不允许与 t.main.wedeep.com.cn 进行 CLEARTEXT 通信
java.net.UnknownServiceException: CLEARTEXT communication to t.main.wedeep.com.cn not permitted by network security policy
我在使用mockhttpserver测试http请求的时候遇到了上面的错误,下面是我创建服务的代码。
fun <T> getService(clazz: Class<T>): T {
val client = OkHttpClient.Builder().addInterceptor(HeaderInterceptor()).addInterceptor(HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE })
.build()
return Retrofit.Builder()
.baseUrl(mockWebServer.url(""))
.client(client)
.addConverterFactory(GsonConverterFactory.create(GSON))
.build()
.create(clazz)
}
这是我的测试代码。
@UninstallModules(HomePageDataModule::class)
@HiltAndroidTest
class TestHomePageViewModel {
private lateinit var viewModel: HomePageViewModel
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Inject
lateinit var cpd: CompositionDao
@Inject
lateinit var csd: CompositionsDao
@Inject
lateinit var hpds: HomePageDataSource
@Inject
lateinit var ss :HomePageService
@Before
fun init() {
hiltRule.inject()
viewModel = HomePageViewModel(HomeCompositionsRepository(cpd, csd, hpds, Util.GSON))
}
@Test
fun testObserveHomeData() {
val data = Util.getFileString("mainpage.json")
val rr = GSON.fromJson(data,Array<HomePreviewView>::class.java)
println(rr)
enqueueResponse("mainpage.json")
runBlocking {
val result = ss.getHomeData()
Assert.assertNotEquals(rr.size,result.body()!!.size)
}
}
我的应用程序一切正常,除了 运行我的单元测试代码。
有一个类似的 ,但我的问题与那个问题相比有点不同。
我已经尝试了很多类似问题的方法,但没有用。
PS:如果测试代码运行在Junit4Test上而不是在AndroidJunit4Test上,则可以正常运行。但现在我需要执行集成测试。所以这部分代码需要在AndroidJunit4Test
上执行
解1)
将以下属性添加到 AndroidManifest.xml 中的 <application
标记:
android:usesCleartextTraffic="true"
解决方案 2)
将android:networkSecurityConfig="@xml/network_security_config"
添加到app/src/main/AndroidManifest.xml
中的<application
标签:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme">
在app/src/main/res/xml/
中对应network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
根据@Yuri Schimke 提示问题终于解决了
第一步:mockwebserver使用https
val mockWebServer = MockWebServer().apply {
val localhost: String = InetAddress.getByName("localhost").canonicalHostName
val localhostCertificate: HeldCertificate = HeldCertificate.Builder().addSubjectAlternativeName(localhost)
.build()
val serverCertificates = HandshakeCertificates.Builder()
.heldCertificate(localhostCertificate)
.build()
useHttps(serverCertificates.sslSocketFactory(), false)
}
第二步:使用不安全的okhttp客户端
private fun getUnsafeOkHttpClient(): OkHttpClient.Builder? {
return try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts: Array<TrustManager> = arrayOf<TrustManager>(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
}
)
// Install the all-trusting trust manager
val sslContext: SSLContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory: SSLSocketFactory = sslContext.getSocketFactory()
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
builder.hostnameVerifier(HostnameVerifier { hostname, session -> true })
builder
} catch (e: Exception) {
throw RuntimeException(e)
}
}
完成此操作后,您可以按照以下代码创建自己的服务。
fun <T> getService(clazz: Class<T>): T {
val client =getUnsafeOkHttpClient()!!.addInterceptor(HeaderInterceptor())
.addInterceptor(HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE })
.build()
return Retrofit.Builder()
.baseUrl(mockWebServer.url(""))
.client(client)
.addConverterFactory(GsonConverterFactory.create(GSON))
.build()
.create(clazz)
}
如果您在 AndroidJunit4 上进行了 okhttp 单元测试,希望这对您有所帮助
就我而言,我将其添加到 android 清单文件中:
android:usesCleartextTraffic="true"
我在使用mockhttpserver测试http请求的时候遇到了上面的错误,下面是我创建服务的代码。
fun <T> getService(clazz: Class<T>): T {
val client = OkHttpClient.Builder().addInterceptor(HeaderInterceptor()).addInterceptor(HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE })
.build()
return Retrofit.Builder()
.baseUrl(mockWebServer.url(""))
.client(client)
.addConverterFactory(GsonConverterFactory.create(GSON))
.build()
.create(clazz)
}
这是我的测试代码。
@UninstallModules(HomePageDataModule::class)
@HiltAndroidTest
class TestHomePageViewModel {
private lateinit var viewModel: HomePageViewModel
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Inject
lateinit var cpd: CompositionDao
@Inject
lateinit var csd: CompositionsDao
@Inject
lateinit var hpds: HomePageDataSource
@Inject
lateinit var ss :HomePageService
@Before
fun init() {
hiltRule.inject()
viewModel = HomePageViewModel(HomeCompositionsRepository(cpd, csd, hpds, Util.GSON))
}
@Test
fun testObserveHomeData() {
val data = Util.getFileString("mainpage.json")
val rr = GSON.fromJson(data,Array<HomePreviewView>::class.java)
println(rr)
enqueueResponse("mainpage.json")
runBlocking {
val result = ss.getHomeData()
Assert.assertNotEquals(rr.size,result.body()!!.size)
}
}
我的应用程序一切正常,除了 运行我的单元测试代码。
有一个类似的
PS:如果测试代码运行在Junit4Test上而不是在AndroidJunit4Test上,则可以正常运行。但现在我需要执行集成测试。所以这部分代码需要在AndroidJunit4Test
上执行解1)
将以下属性添加到 AndroidManifest.xml 中的 <application
标记:
android:usesCleartextTraffic="true"
解决方案 2)
将android:networkSecurityConfig="@xml/network_security_config"
添加到app/src/main/AndroidManifest.xml
中的<application
标签:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme">
在app/src/main/res/xml/
中对应network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
根据@Yuri Schimke 提示问题终于解决了
第一步:mockwebserver使用https
val mockWebServer = MockWebServer().apply {
val localhost: String = InetAddress.getByName("localhost").canonicalHostName
val localhostCertificate: HeldCertificate = HeldCertificate.Builder().addSubjectAlternativeName(localhost)
.build()
val serverCertificates = HandshakeCertificates.Builder()
.heldCertificate(localhostCertificate)
.build()
useHttps(serverCertificates.sslSocketFactory(), false)
}
第二步:使用不安全的okhttp客户端
private fun getUnsafeOkHttpClient(): OkHttpClient.Builder? {
return try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts: Array<TrustManager> = arrayOf<TrustManager>(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
}
)
// Install the all-trusting trust manager
val sslContext: SSLContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory: SSLSocketFactory = sslContext.getSocketFactory()
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
builder.hostnameVerifier(HostnameVerifier { hostname, session -> true })
builder
} catch (e: Exception) {
throw RuntimeException(e)
}
}
完成此操作后,您可以按照以下代码创建自己的服务。
fun <T> getService(clazz: Class<T>): T {
val client =getUnsafeOkHttpClient()!!.addInterceptor(HeaderInterceptor())
.addInterceptor(HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE })
.build()
return Retrofit.Builder()
.baseUrl(mockWebServer.url(""))
.client(client)
.addConverterFactory(GsonConverterFactory.create(GSON))
.build()
.create(clazz)
}
如果您在 AndroidJunit4 上进行了 okhttp 单元测试,希望这对您有所帮助
就我而言,我将其添加到 android 清单文件中:
android:usesCleartextTraffic="true"