如何使用 jsonrpc4j 客户端将对象作为参数传递?
Posted
技术标签:
【中文标题】如何使用 jsonrpc4j 客户端将对象作为参数传递?【英文标题】:How do I pass objects as parameters using the jsonrpc4j client? 【发布时间】:2020-09-17 16:37:38 【问题描述】:我正在尝试编写一个 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)
...
https://github.com/xiaocong/android-uiautomator-server/blob/master/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorService.java#L400
这是我的测试代码:
@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, 主机=localhost:9008, 内容类型=应用程序/json-rpc,连接=保持活动, 缓存控制=无缓存,编译指示=无缓存,用户代理=Java/1.8.0_265, 接受=文本/html、图像/gif、图像/jpeg、*; q=.2, /; q=.2,参数, 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,"focused" :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")
注释类,但唯一的效果是它为“params”添加了一个“类”属性。
如何使它工作,以便我可以在客户端使用服务器的参数类型?
【问题讨论】:
为什么不试试 Kotlin 序列化:github.com/Kotlin/kotlinx.serialization 【参考方案1】:任何参数都必须传递到数组中。因此,在您的情况下,JAVA 中的代码将是:
Boolean exists = client.invoke("exist", new Object[]selector, Boolean.class);
【讨论】:
以上是关于如何使用 jsonrpc4j 客户端将对象作为参数传递?的主要内容,如果未能解决你的问题,请参考以下文章
如何将复杂的 Java 类对象作为参数传递给 Spark 中的 Scala UDF?
如何将json POST数据作为对象传递给Web API方法?