如何解决错误:无效的 JSON 输入:无法从 START_ARRAY 令牌中反序列化 Topic 实例

Posted

技术标签:

【中文标题】如何解决错误:无效的 JSON 输入:无法从 START_ARRAY 令牌中反序列化 Topic 实例【英文标题】:How to solve the error: Invalid JSON input: Cannot deserialize instance of Topic out of START_ARRAY token 【发布时间】:2020-06-15 06:13:06 【问题描述】:

我正在开发一个使用 Springboot Rest API 和 ReactJS 前端的调查应用程序,我面临一个看似无法解决的问题。在我的 Springboot 应用程序中,我有一个名为 Topic 的 bean,它的编写如下:

@Entity
public class Topic 
    @Id
    @GeneratedValue
    private Long id;

    private String question;

    @NotNull
    @Size(min=3, max=20)
    private String topic;

    @Column(precision=4, scale=1)
    private double npm = 0;

    @OneToMany(mappedBy = "topic")
    private Set<Submission> submissions;

    public Topic()
    
        super();
    

    public Topic(Long id, String topic, double npm)
    
        super();
        this.id = id;
        this.setTopic(topic);
        this.setNpm(npm);
    

    public Long getID()
    
        return this.id;
    

    public void setId(Long id)
    
        this.id = id;
    

    /**
     * @return the topic
     */
    public String getTopic() 
        return topic;
    

    /**
     * @param topic the topic to set
     */
    public void setTopic(String topic) 
        this.topic = topic;
    

    /**
     * @return the npm
     */
    public double getNpm() 
        return npm;
    

    /**
     * @param npm the npm to set
     */
    public void setNpm(double npm) 
        this.npm = npm;
    

    /**
     * @return the question
     */
    public String getQuestion() 
        return question;
    

    /**
     * @param question the question to set
     */
    public void setQuestion(String question) 
        this.question = question;
    


还有一个存储库类:

@Repository
public interface TopicRepository extends JpaRepository<Topic, Long>

    @Transactional
    @Modifying
    @Query("UPDATE Topic SET npm = ?1 WHERE id = ?2")
    public void updateNpm(double newNpm, long id);

    @Query("SELECT topic FROM Topic")
    public List<String> getTopics();


最后,我的Controller类如下(我省略了不会引起问题的方法):

@RestController
public class TopicResource 

    @Autowired
    private TopicRepository topicRepository;

    @CrossOrigin
    @PostMapping("/topics")
    public void createTopic(@RequestBody Topic topic)
    
        Topic savedTopic = topicRepository.save(topic);
    

在我的 React 应用程序中,我正在从以下组件类发出 POST 请求:

import React,  Component  from 'react';
import './Styling/createsurvey.css'

class CreateSurvey extends Component 

    constructor () 
        super();
        this.state = 
            topic: '',
            question: ''
        ;

        this.handleTopicChange = this.handleTopicChange.bind(this);
        this.handleQuestionChange = this.handleQuestionChange.bind(this);
        //this.printState = this.printState.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    

    handleTopicChange(e) 
        this.setState(
            topic: e.target.value
        );
    

    handleQuestionChange(e) 
        this.setState(
            question: e.target.value
        );
    

    handleSubmit(event) 
        event.preventDefault();

        console.log(this.state.topic);
        console.log(this.state.question);

        fetch('http://localhost:8080/topics', 
            method: 'post',
            headers: 'Content-Type':'application/json',
            body: 
                "npm": "0",
                "topic": "Turkey",
                "question": "How is life here",
                "submissions": 
            
           );


    

    render() 
        return(
           <div>
               <form onSubmit=this.handleSubmit>
                   <h2>Create a new Survey</h2>
                   <br></br>
                   <div className="form-group">
                        <label><strong>Enter the survery topic: </strong></label>
                        <br></br>
                        <input 
                        className="form-control" 
                        placeholder="Enter a cool topic to ask a question about"
                        align="left"
                        onChange=this.handleTopicChange>        
                        </input>
                   </div>
                   <div className="form-group">
                        <label><strong>Enter a survey question: </strong></label>
                        <br></br>
                        <textarea
                        className="form-control" 
                        placeholder="Ask your question here. The customer will give an answer on a scale from 1 to 10."
                        align="left"
                        rows="3"
                        onChange=this.handleQuestionChange>        
                        </textarea>
                   </div>
                   <div className="form-group">
                    <button type="submit" className="btn btn-primary">Submit Your Question</button>
                   </div>   
            </form>
           </div>
        );
    



export default CreateSurvey;

我遇到以下错误:

2020-03-03 01:15:17.862 DEBUG 17816 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : POST "/topics", parameters=
2020-03-03 01:15:17.862 DEBUG 17816 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.recommend.me.springboot.rest.recommendme.topic.TopicResource#createTopic(Topic)
2020-03-03 01:15:17.867 DEBUG 17816 --- [nio-8080-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Could not resolve parameter [0] in public void com.recommend.me.springboot.rest.recommendme.topic.TopicResource.createTopic(com.recommend.me.springboot.rest.recommendme.topic.Topic): Invalid JSON input: Cannot deserialize instance of `com.recommend.me.springboot.rest.recommendme.topic.Topic` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.recommend.me.springboot.rest.recommendme.topic.Topic` out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 1]

有人可以指出我的请求做错了什么吗?我尝试了所有形式的 JSON 请求格式,但似乎没有任何效果。

【问题讨论】:

Submission 是 Topic 类下的一个集合,希望你也有反序列化 Submission 的要求,因为我看不到任何 setter getter。您可以在 post json 中尝试 "submissions": [] 而不是 "submissions": 吗? 我没有为提交类设置任何反序列化要求。你能告诉我应该怎么做吗?另外,我尝试将 "submissions": 更改为 "submissions": [] 并没有成功。 【参考方案1】:

在将序列化的主题对象发送到控制器时,您需要对正文进行字符串化。 JSON.stringify 应该可以解决这个问题。

检查下面的代码并链接到jsfiddle。

fetch('http://localhost:8080/topics', 
            method: 'post',
            headers: 'Content-Type':'application/json',
            body: JSON.stringify(
                "npm": "0",
                "topic": "Turkey",
                "question": "How is life here",
                "submissions": 
            )
           )

    .then(function (response) 
    return response.json();
)
    .then(function (result) 
    alert(result)
)
    .
catch (function (error) 
    console.log('Request failed', error);
);

【讨论】:

是的,这解决了问题。非常感谢!

以上是关于如何解决错误:无效的 JSON 输入:无法从 START_ARRAY 令牌中反序列化 Topic 实例的主要内容,如果未能解决你的问题,请参考以下文章

使用 .net 核心 json 模型绑定在无效 json 上引发 json 验证错误

JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 `byte[]` 的实例

如何修复来自 Google Ads API 的无效 JSON 负载错误

LoadRunner 运行负载测试提示 无法联机创建:无效指针 ;如何解决?

如何修复 Magento 中的错误“无法建立 FTP 连接,无效的主机或端口”

如何解决“证书无效且无法用于验证本网站的身份”错误?