简体   繁体   English

如何使用 Spring 设置 RESTful API 以使用 Controller 和 Model 发送 JSON 响应

[英]How to set up a RESTful API with Spring to send a JSON response with Controller and Model

I am trying to set up a RESTful API using Spring so that I can send an HTTP POST request and receive a response.我正在尝试使用 Spring 设置RESTful API,以便我可以发送HTTP POST 请求并接收响应。

The post request that I'm testing with looks exactly like this:我正在测试的 post 请求看起来完全像这样:

POST http://localhost:8081/decide
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json

{
  "previousDecisions": [0, 1, 2]
}

When I send that request (I'm using IntelliJ's 'Test RESTful Web Services' feature) I am getting an error response.当我发送该请求(我正在使用IntelliJ's “测试RESTful Web 服务”功能)时,我收到了错误响应。

What I want to happen is, there is a class called Decide with a constructor that needs only an array of integers and its only member variable is an array of integers.我想要发生的是,有一个名为Decide的类,它的构造函数只需要一个整数数组,它唯一的成员变量是一个整数数组。 I want to pass the above request to the DecideController to create an instance of Decide .我想将上述请求传递给DecideController以创建一个Decide实例。 Then Decide has a method that returns a Node object.然后Decide有一个返回Node对象的方法。 I want to return a JSON version of that Node instance.我想返回该Node实例的 JSON 版本。

From what I've seen with Spring it automatically converts a Java object to a JSON format when it returns.从我在 Spring 中看到的情况来看,它在返回时会自动将 Java 对象转换为 JSON 格式。

Here is my entire Decide class:这是我的整个 Decide 课程:

package com.thesisapp.server.jugtours.model;

import java.io.Serializable;

public class Decide implements Serializable {

  private int[] decisionList;

  public Decide() {
    this.decisionList = new int[0];
  }

  public Decide(int[] decisionList) {
    this.decisionList = decisionList;
  }

  public Node getNode() {
    //Use the game class to get a root node for the entire story tree
    Node rootNode = (new Game()).getFullStoryTree();

    //Traverse the story tree using the decisionList to get to the current node
    Node currentNode = rootNode;
    for (int whichChild : this.decisionList) {
      currentNode = currentNode.getChild(whichChild);
    }

    return currentNode;
  }
}

Side Note: I just added the implements Serializable after doing some research and it did not have an affect on the error message I received.旁注:我只是在做了一些研究后添加了可implements Serializableimplements Serializable ,它对我收到的错误消息没有影响。 However adding that default constructor did have an affect on the error message.但是,添加默认构造函数确实对错误消息有影响。

And here is my entire DecideController class这是我的整个 DecideController 类

package com.thesisapp.server.jugtours.web;

import com.thesisapp.server.jugtours.model.Node;
import com.thesisapp.server.jugtours.model.Decide;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@RestController
public class DecideController {

  @PostMapping("/decide")
  public Node decide(@RequestBody Decide decide) {
    return decide.getNode();
  }
}

Again here is the request I am sending in:这里再次是我发送的请求:

POST http://localhost:8081/decide
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json

{
  "previousDecisions": [0, 1, 2]
}

Here is what I want the response to look like, just JSON form of all the member variables from the Node class:这是我希望响应的样子,只是Node类中所有成员变量的 JSON 形式:

{
  "id": 0,
  "text": "some text here",
  "decisions": [],
  "children": [],
  "speaker": 0,
  "checkpoint": true
}

Here are the two responses I have managed to get (before and after adding that default constructor to the Decide class)这是我设法得到的两个响应(在将默认构造函数添加到Decide类之前和之后)

{
  "timestamp": "2019-09-04T02:31:05.762+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "Type definition error: [simple type, class com.thesisapp.server.jugtours.model.Decide]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.thesisapp.server.jugtours.model.Decide` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (PushbackInputStream); line: 2, column: 3]",
  "path": "/decide"
}
{
  "timestamp": "2019-09-04T01:50:03.990+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "No message available",
  "path": "/decide"
}

I don't really have any idea at what is going wrong here.我真的不知道这里出了什么问题。 Let me know if I didn't provide enough info/code.如果我没有提供足够的信息/代码,请告诉我。 I have very little experience with this stuff but I appreciate any help, thank you!!我对这些东西的经验很少,但我很感激任何帮助,谢谢!!

You need getters/setters for decisionList on the Decide class so Jackson can properly bind to it.您需要在Decide类上的decisionList getter/setter 方法,以便 Jackson 可以正确绑定到它。 In addition your JSON request body does not map to the Decide object you've defined.此外,您的 JSON 请求正文不会映射到您定义的 Decide 对象。 By passing in通过传入

{
  "previousDecisions": [0, 1, 2]
}

Your Decide class should look like this:您的 Decide 类应如下所示:

public class Decide {
   private int[] previousDecisions;

   public int[] getPreviousDecisions(){
      return previousDecisions;  
   }

   public void setPreviousDecisions(int[] previousDecisions){
      this.previousDecisions = previousDecisions;
   }
}

So either change your field name in Decide from decisionList to previousDecisions and add getters/setters, or pass decisionList as the property in JSON and add getters/setters to the class:因此,要么将Decide的字段名称从decisionList更改为previousDecisions并添加 getter/setter,要么将decisionList作为 JSON 中的属性传递,并将 getter/setter 添加到类中:

{   
   "decisionList": [0, 1, 2]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM