Ajax 调用在 Spring Boot 中返回值为 JSONArray.fromObject(data) 时给出错误 500

Posted

技术标签:

【中文标题】Ajax 调用在 Spring Boot 中返回值为 JSONArray.fromObject(data) 时给出错误 500【英文标题】:Ajax call is giving error 500 while returning value as JSONArray.fromObject(data) in Spring boot 【发布时间】:2021-03-20 00:39:44 【问题描述】:

我正在尝试将一些 jsonArray 值添加到我的 ajax 响应正文中。但它一直给出错误500。我可以看到调用在控制器上并且还打印了值。但由于某种原因,它不会进入 ajax 响应体。如果我要返回课程,那么我可以看到 ajax 调用工作正常,但是当我试图将这些值传递给 jsonArray 时。我正在使用 Spring Boot。 我遇到了这种类型的错误。

GET http://localhost:5000/report/id?=2 500

ajax 调用:

  $.ajax(
           type: "GET",
           url: "/report",
           data: 
             id: id
            ,
           success: function (response) 
                console.log(response)

      ,
   );

控制器:

@RestController

 @Autowired
 ReportDAO reportDao;

 @GetMapping(value = "/report")
 public @ResponseBody JSONArray getReport(@RequestParam(value="id") Integer id) 
  JsonArray report = new JSONArray();
  try 
     report = JSONArray.fromObject(reportDao.getReportById(id));
  catch(Ex e)

  
  System.out.println(report); // this is returing the value but not in the main ajax resposne call
   return report;


我得到一个我的控制器的数据是这种格式:

[
  "dataUrl: "va",
  "id": 1,
  "status": "active",
  "dataJson": "[
    "id": 1,
    "name": "Jon"
   ]

]

【问题讨论】:

您的错误实际上很可能是由于 Spring 在内部尝试使用 Jackson(JSON 库)将 JSONArray 中的字段转换为 JSON 对象。 ...因此,无论 reportDao.getReportById(id) 的返回类型是什么,都在此控制器方法上设置返回类型,Spring 应该自动为您将其转换为 JSON 另一种选择(不太理想),您可以返回类型 String 而不是 JSONArray 并返回 report.toString() 【参考方案1】:

那是因为你做错了 ajax 调用。您的控制器设置为期望 id 作为请求参数而不是正文。反过来,这意味着您应该点击的 URL 应如下所示:

/report/id

而不是将其作为请求正文的一部分传递。这反过来会导致您看到的 500 错误,因为 Spring 除外,因为默认情况下 RequestParam#required 的值是 true

最后不是,虽然您可以将 GET 与请求正文一起使用,但我建议您不要这样做,因为这不是一个好习惯。

【讨论】:

我尝试过你所说的 /report?id="+id, 它仍然给出 500 错误。如果我返回我的类"report",ajax 调用没有给出任何错误,但是当我试图获取该值作为 JsonArray 时,我得到了错误。控制器已打印值,但 ajax 调用给出 500 您应该包含任何类型的应用程序日志和堆栈跟踪以帮助您。【参考方案2】:

所以看起来 springboot 最有可能尝试将 JSONArray 中的内部工作字段序列化为 JSON,这不是你想要的。

Spring 在内部使用 Jackson(一个 JSON 解析器)在 JSON 和 Java 类之间自动转换。因此,如果您返回您的 DAO 类型而不是 JsonArray,Spring 将在幕后调用 Jackson 并使用类似 new ObjectMapper().writeValueAsString(myDAOReturnType)

比如:

@GetMapping(value = "/report/id")
public @ResponseBody MyDAOType getReport(@PathVariable(value="id") Integer id) 
   MyDAOType report;
   try 
      report = reportDao.getReportById(id);
    catch(Ex e)
        // handle error
   
   return report;

其中 MyDAOType 是从reportDao.getReportById(id); 返回的类型

注意:在我的示例中,我还改用了 PathVariable,因为这似乎更适合您的场景。

【讨论】:

以上是关于Ajax 调用在 Spring Boot 中返回值为 JSONArray.fromObject(data) 时给出错误 500的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot中调用@Async注解的异步方法并获取返回值

Spring Boot中调用@Async注解的异步方法并获取返回值

Spring Boot中调用@Async注解的异步方法并获取返回值

记录Spring Boot小项目的一些坑

带有模型和百里香叶的 Spring Boot Ajax 发布表单提交

在 Spring Boot Web Thymeleaf 应用程序中进行 AJAX 调用的正确方法是获取 getOutputStream() 已经为此响应调用