【问题标题】:Tornadofx REST clientTornadofx REST 客户端
【发布时间】:2020-06-29 17:27:08
【问题描述】:

我按照此处显示的示例进行操作

link

我掌握了窍门,我设法创建了自己的“员工”实体,并且我在网上找到了一些虚拟 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 发送请求,您将收到我所说的错误

【问题讨论】:

    标签: json rest kotlin tornadofx


    【解决方案1】:

    您对 mocky 的调用会返回一个列表,因此 .list() 可以正常工作。但是,您对 restapiexample 的调用会返回一个对象,而不是一个列表,因此 .list() 不会达到您的预期。您可能可以使用这样的东西,虽然我还没有测试过:

    response.one().getJsonArray("data").toModel<Employee>()[0].name)
    

    进一步解释:

    如果您不熟悉 JSON 的结构,请查看 the JSON homepage 上的图表。

    TornadoFX 有两个用于处理 JSON 返回的便捷函数:.list().one().list() 函数将检查结果是否为JsonArray。如果是这样,它只是返回它。如果它是 JsonObject,它会将该对象包装在一个列表中并返回新列表。

    在您的情况下,由于 restapiexample 返回一个对象,因此您调用 .list() 的结果是一个带有单个对象的 JsonArray。它看起来像这样:

    [
      {
        "status": "success",
        "data": [...]
      }
    ]
    

    显然,单个对象无法转换为 Employee,因此取消引用它的任何内容将导致 NullPointerException

    另一方面,.one() 函数将检查响应是否为JsonObject。如果是,它只是返回对象。但是,如果响应是 JsonArray,它将从数组中取出第一项并返回该项。

    【讨论】:

      猜你喜欢
      • 2013-07-07
      • 2014-05-15
      • 1970-01-01
      • 2023-04-04
      • 2018-10-01
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      • 2017-03-31
      相关资源
      最近更新 更多