Tornadofx REST 客户端
Tornadofx REST client
我按照此处显示的示例进行操作
我掌握了窍门,我设法创建了自己的“员工”实体,并且在网上找到了一些虚拟 api 数据来玩。
like this 问题是,tornadofx 抛出空指针错误,我认为这是因为其余响应发送了类似这样的内容
{
"status": "success",
"data": [
{
"id": "1",
"employee_name": "Tiger Nixon",
"employee_salary": "320800",
"employee_age": "61",
"profile_image": ""
},
但是当我使用 mocky 并仅提供 json 部分时
[
{
"id": "1",
"employee_name": "Tiger Nixon",
"employee_salary": "320800",
"employee_age": "61",
"profile_image": ""
},...]
一切正常。
我认为响应中的那些附加字段“状态”和“成功”混淆了 tornadofx 的其余客户端,我无法让它工作,无论如何告诉客户端忽略除 json 之外的所有其他字段数据。
所有链接都是有效的,你可以自己试试。
完整的工作示例
package com.example.demo.view
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleStringProperty
import javafx.scene.layout.BorderPane
import tornadofx.*
import javax.json.JsonObject
class Employee (id:Int?=null , name: String? = null, age: Int?=null): JsonModel {
val idProperty = SimpleIntegerProperty(this, "id")
var id by idProperty
val ageProperty = SimpleIntegerProperty(this, "age")
var age by ageProperty
val employeeNameProperty = SimpleStringProperty(this, "name", name)
var name by employeeNameProperty
override fun updateModel(json: JsonObject) {
with(json) {
id = int("id")!!
age = int("employee_age")!!
name = string("employee_name")
}
}
override fun toJSON(json: JsonBuilder) {
with(json) {
add("id", id)
add("employee_name", name)
add("employee_age", age)
}
}
}
class PersonEditor : View("Person Editor") {
override val root = BorderPane()
val api : Rest by inject()
var persons = listOf(Employee(1,"John", 44), Employee(2,"Jay", 33)).observable()
val model = PersonModel(Employee())
init {
api.baseURI = "https://run.mocky.io/v3/"
val response = api.get("f17509ba-2d12-4c56-b441-69ab23302e43")
println(response.list())
println(response.list().toModel<Employee>()[0].name)
// print( p.get(1))
with(root) {
center {
tableview(response.list().toModel<Employee>()) {
column("Id", Employee::idProperty)
column("Name", Employee::employeeNameProperty)
column("Age", Employee::ageProperty)
// Update the person inside the view model on selection change
model.rebindOnChange(this) { selectedPerson ->
item = selectedPerson ?: Employee()
}
}
}
right {
form {
fieldset("Edit person") {
field("Id") {
textfield(model.id)
}
field("Name") {
textfield(model.name)
}
field("Age") {
textfield(model.age)
}
button("Save") {
enableWhen(model.dirty)
action {
save()
}
}
button("Reset").action {
model.rollback()
}
}
}
}
}
}
private fun save() {
// Flush changes from the text fields into the model
model.commit()
// The edited person is contained in the model
val person = model.item
// A real application would persist the person here
println("Saving ${person.employeeNameProperty} / ${person.ageProperty}")
}
}
class PersonModel(person: Employee) : ItemViewModel<Employee>(person) {
val id = bind(Employee::idProperty)
val name = bind(Employee::employeeNameProperty)
val age = bind(Employee::ageProperty)
}
如果您替换基础 url 并将请求发送到 http://dummy.restapiexample.com/api/v1/employees,您将收到我正在谈论的错误
您对 mocky return 的调用是一个列表,因此 .list()
工作正常。但是,您对 restapiexample 的调用 return 是一个对象,而不是列表,因此 .list()
不会执行您期望的操作。你可能可以使用这样的东西,虽然我还没有测试过:
response.one().getJsonArray("data").toModel<Employee>()[0].name)
进一步说明:
如果您不熟悉 JSON 的结构,请查看 the JSON homepage 上的图表。
TornadoFX 有两个使用 JSON returns 的便捷函数:.list()
和 .one()
。 .list()
函数将检查结果是否为 JsonArray
。如果是这样,它只是 returns 它。如果它是一个 JsonObject
,它会将那个对象包装在一个列表中并且 return 是新列表。
在您的情况下,由于 restapiexample 正在 returning 对象,因此您调用 .list()
的结果是具有单个对象的 JsonArray。它看起来像这样:
[
{
"status": "success",
"data": [...]
}
]
显然,单个对象不能转换为 Employee
,因此取消引用它的任何内容将导致 NullPointerException
.
另一方面,.one()
函数将检查响应是否为 JsonObject
。如果是,它只是 return 对象。但是,如果响应是 JsonArray
,它将从数组中获取第一项,然后 return 该项。
我按照此处显示的示例进行操作
我掌握了窍门,我设法创建了自己的“员工”实体,并且在网上找到了一些虚拟 api 数据来玩。 like this 问题是,tornadofx 抛出空指针错误,我认为这是因为其余响应发送了类似这样的内容
{
"status": "success",
"data": [
{
"id": "1",
"employee_name": "Tiger Nixon",
"employee_salary": "320800",
"employee_age": "61",
"profile_image": ""
},
但是当我使用 mocky 并仅提供 json 部分时
[
{
"id": "1",
"employee_name": "Tiger Nixon",
"employee_salary": "320800",
"employee_age": "61",
"profile_image": ""
},...]
一切正常。 我认为响应中的那些附加字段“状态”和“成功”混淆了 tornadofx 的其余客户端,我无法让它工作,无论如何告诉客户端忽略除 json 之外的所有其他字段数据。
所有链接都是有效的,你可以自己试试。
完整的工作示例
package com.example.demo.view
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleStringProperty
import javafx.scene.layout.BorderPane
import tornadofx.*
import javax.json.JsonObject
class Employee (id:Int?=null , name: String? = null, age: Int?=null): JsonModel {
val idProperty = SimpleIntegerProperty(this, "id")
var id by idProperty
val ageProperty = SimpleIntegerProperty(this, "age")
var age by ageProperty
val employeeNameProperty = SimpleStringProperty(this, "name", name)
var name by employeeNameProperty
override fun updateModel(json: JsonObject) {
with(json) {
id = int("id")!!
age = int("employee_age")!!
name = string("employee_name")
}
}
override fun toJSON(json: JsonBuilder) {
with(json) {
add("id", id)
add("employee_name", name)
add("employee_age", age)
}
}
}
class PersonEditor : View("Person Editor") {
override val root = BorderPane()
val api : Rest by inject()
var persons = listOf(Employee(1,"John", 44), Employee(2,"Jay", 33)).observable()
val model = PersonModel(Employee())
init {
api.baseURI = "https://run.mocky.io/v3/"
val response = api.get("f17509ba-2d12-4c56-b441-69ab23302e43")
println(response.list())
println(response.list().toModel<Employee>()[0].name)
// print( p.get(1))
with(root) {
center {
tableview(response.list().toModel<Employee>()) {
column("Id", Employee::idProperty)
column("Name", Employee::employeeNameProperty)
column("Age", Employee::ageProperty)
// Update the person inside the view model on selection change
model.rebindOnChange(this) { selectedPerson ->
item = selectedPerson ?: Employee()
}
}
}
right {
form {
fieldset("Edit person") {
field("Id") {
textfield(model.id)
}
field("Name") {
textfield(model.name)
}
field("Age") {
textfield(model.age)
}
button("Save") {
enableWhen(model.dirty)
action {
save()
}
}
button("Reset").action {
model.rollback()
}
}
}
}
}
}
private fun save() {
// Flush changes from the text fields into the model
model.commit()
// The edited person is contained in the model
val person = model.item
// A real application would persist the person here
println("Saving ${person.employeeNameProperty} / ${person.ageProperty}")
}
}
class PersonModel(person: Employee) : ItemViewModel<Employee>(person) {
val id = bind(Employee::idProperty)
val name = bind(Employee::employeeNameProperty)
val age = bind(Employee::ageProperty)
}
如果您替换基础 url 并将请求发送到 http://dummy.restapiexample.com/api/v1/employees,您将收到我正在谈论的错误
您对 mocky return 的调用是一个列表,因此 .list()
工作正常。但是,您对 restapiexample 的调用 return 是一个对象,而不是列表,因此 .list()
不会执行您期望的操作。你可能可以使用这样的东西,虽然我还没有测试过:
response.one().getJsonArray("data").toModel<Employee>()[0].name)
进一步说明:
如果您不熟悉 JSON 的结构,请查看 the JSON homepage 上的图表。
TornadoFX 有两个使用 JSON returns 的便捷函数:.list()
和 .one()
。 .list()
函数将检查结果是否为 JsonArray
。如果是这样,它只是 returns 它。如果它是一个 JsonObject
,它会将那个对象包装在一个列表中并且 return 是新列表。
在您的情况下,由于 restapiexample 正在 returning 对象,因此您调用 .list()
的结果是具有单个对象的 JsonArray。它看起来像这样:
[
{
"status": "success",
"data": [...]
}
]
显然,单个对象不能转换为 Employee
,因此取消引用它的任何内容将导致 NullPointerException
.
另一方面,.one()
函数将检查响应是否为 JsonObject
。如果是,它只是 return 对象。但是,如果响应是 JsonArray
,它将从数组中获取第一项,然后 return 该项。