Void SpringMVC Ajax 控制器上的“JSON 输入意外结束”

Posted

技术标签:

【中文标题】Void SpringMVC Ajax 控制器上的“JSON 输入意外结束”【英文标题】:"Unexpected end of JSON input" on a Void SpringMVC Ajax Controller 【发布时间】:2019-10-02 00:53:42 【问题描述】:

我有一个 SpringMVC/Thymeleaf 应用程序,如果我返回 boolean,以下 Ajax 处理工作得非常好。但是,只要方法是void,就会出现错误 Unexpected end of JSON input 在 Firebug 中。这是一个 POST 请求。

@ResponseBody
@PostMapping("/addOrUpdate")
public void /*boolean works!*/ addOrUpdate(@RequestBody String json) throws Exception 
    service.addOrUpdateUserRoles(json);
    /*boolean works - return true;*/

JS

 $.ajax(
        type : "post",
        dataType : 'json',
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : id 
 )
 .then(function() 
     //...
 )
 .fail(function(jqXHR, textStatus, errorThrown) 
     //...
 );

如果我只是从方法定义中删除 @ResponseBody,Thymeleaf 会抱怨, org.thymeleaf.exceptions.TemplateInputException: Error resolving template [addOrUpdate], template might not exist or might not be accessible by any of the configured Template Resolvers

我按照ResponseEntity 示例here 进行操作,但没有帮助——同样的错误,JS 进入错误部分并出现意外的输入结束。

@ResponseBody
@PostMapping("/addOrUpdate")
public ResponseEntity addOrUpdate(@RequestBody String json) throws Exception 
    service.addOrUpdate(json);
    return new ResponseEntity(HttpStatus.OK);
       

【问题讨论】:

【参考方案1】:

基于digitalbreed's answer的最终解决方案

控制器

@PostMapping("/addOrUpdate")
public ResponseEntity<String> addOrUpdate(@RequestBody String json) throws Exception 
    try 
        service.addOrUpdate(json);
        return new ResponseEntity<String>(HttpStatus.OK); // No exceptions
    
    catch (Exception e) 
        log.error("Error", e);
        return new ResponseEntity<String>(HttpStatus.BAD_REQUEST); // This will enable JS to catch the Exception from Ajax
    
   

JS

 $.ajax(
        type : "post",
        dataType : 'text', // Returns a ResponseEntity, not JSON (Void method)
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : somedata
 )
 .then(function() 
      //...
 )
 .fail(function(jqXHR, textStatus, errorThrown) 
      //... - will come here for a ResponseEntity of 'Bad Request'
 );

【讨论】:

【参考方案2】:

正如例外所说,失败点是输入。 需要发送json格式输入。

$.ajax(
        type : "post",
        dataType : 'json',
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : id: id
... 

【讨论】:

【参考方案3】:

使用dataType : 'json',您是在告诉 jQuery 您期望 JSON 作为响应。空响应不是有效的 JSON,错误消息 Unexpected end of JSON input 正是告诉您这一点。

如果您不打算从 addOrUpdate 控制器方法返回任何内容,请删除 @ResponseBody 注释,因为没有响应正文,并坚持使用 ResponseEntity 但使用 HttpStatus.NO_CONTENT 代替通知客户端响应没有预期的内容。另外,将您的 dataType 更改为可能为空的内容,例如 'text'

【讨论】:

我按照你说的做了一切,但返回了 HttpStatus.OK,因为这似乎提供了更多信息,而且它正在工作。非常感谢!! @geneb."no content" 也是一种“成功”响应状态——事实上,它的信息量更大,因为它传达了预期没有内容的附加信息。见developer.mozilla.org/en-US/docs/Web/HTTP/…

以上是关于Void SpringMVC Ajax 控制器上的“JSON 输入意外结束”的主要内容,如果未能解决你的问题,请参考以下文章

Ajax jQuery 调用上的 415 错误 - Spring MVC 控制器

springmvc用@crossorigin解决跨域 ajax怎么写

ajax post提交到SpringMVC的Controller并将处理结果传递到前台输出总结-- springmvc 控制器获取参数的几种方式

SpringMVC+AJAX+JSON

Spring MVC + Ajax 错误 400

多个 ajax 数据到 Spring MVC 控制器