Как передать объекты в качестве параметров с помощью клиента jsonrpc4j?
Я пытаюсь написать клиент Kotlin, который использует jsonrpc4j (https://github.com/briandilley/jsonrpc4j) для разговора с сервером, работающим на устройстве Android. Это сервер, который я использую: https://github.com/xiaocong/android-uiautomator-server
Вызов методов, которые принимают одиночные аргументы, например
null
или одинокий
String
объекты работают нормально. Однако, если я попытаюсь вызвать метод
boolean exist(Selector obj);
сопоставление методов не работает, и я получаю исключение:
Invalid method parameters
com.googlecode.jsonrpc4j.JsonRpcClientException: Invalid method parameters
at com.googlecode.jsonrpc4j.DefaultExceptionResolver.createJsonRpcClientException(DefaultExceptionResolver.java:53)
at com.googlecode.jsonrpc4j.DefaultExceptionResolver.resolveException(DefaultExceptionResolver.java:28)
at com.googlecode.jsonrpc4j.JsonRpcClient.handleErrorResponse(JsonRpcClient.java:272)
at com.googlecode.jsonrpc4j.JsonRpcClient.readResponse(JsonRpcClient.java:196)
at com.googlecode.jsonrpc4j.JsonRpcClient.readResponse(JsonRpcClient.java:531)
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:148)
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:118)
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:176)
...
Вот мой тестовый код:
@Test fun methodTest() {
val client = JsonRpcHttpClient(URL("http://localhost:9008/jsonrpc/0"))
val invoke = client.invoke("ping", null, Object::class.java)
println(invoke) // prints "pong"
val selector = Selector()
selector.packageName = "com.company.appname"
val exists = client.invoke("exist", selector, Boolean::class.java) // throws Exception
println(exists)
}
Я отладил код сервера, и похоже, что тип Selector утерян, а все параметры "сведены" к списку строк:
09-17 18:05:58.216 D / UIAutomatorStub(17611): URI: / jsonrpc / 0, метод: POST, заголовок: {content-length=620, remote-addr=127.0.0.1, http-client-ip=127.0.0.1, host=localhost:9008, content-type=application/json-rpc, connection=keep-alive, cache-control=no-cache, pragma=no-cache, user-agent=Java/1.8.0_265, принять = текст / HTML, изображение / GIF, изображение / JPEG, *; q=.2, /; q=.2}, params,{NanoHttpd.QUERY_STRING=null}, файлы: {postData={"id":"61840997","jsonrpc":"2.0","method":"exist","params":{"packageName":"com.company.appname","text":null,"className":null,"description":null,"textContains":null,"textMatches":null,"textStartsWith":null,"classNameMatches":null,"descriptionContains":null,"descriptionMatches":null,"descriptionStartsWith":null,"checkable":false,"checked":false,"clickable":false,"scrollable":false,"longClickable":false,"enabled":false,"focusable":false,"focus":false,"selected":false,"packageNameMatches":null,"resourceId":null,"resourceIdMatches":null,"mask":0,"childOrSiblingSelector":[],"childOrSibling":[],"index":0,"instance":0}}}
Я скопировал
Selector
класс с сервера в основной проект и использовал его как есть: https://github.com/xiaocong/android-uiautomator-server/blob/master/app/src/androidTest/java/com/github/uiautomator/stub/Selector.java
Я также пробовал аннотировать класс с помощью
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property="class")
но единственным эффектом было то, что он добавил атрибут "class" к "params".
Как заставить его работать, чтобы я мог использовать типы параметров сервера на стороне клиента?
1 ответ
Любой параметр должен быть передан в массив. Итак, в вашем случае код в JAVA будет:
Boolean exists = client.invoke("exist", new Object[]{selector}, Boolean.class);