【问题标题】:java.lang.StackOverflowError while converting BindingResult to JSON using Gson使用 Gson 将 BindingResult 转换为 JSON 时出现 java.lang.StackOverflowError
【发布时间】:2016-08-30 07:36:09
【问题描述】:

环境:
Spring boot - 1.2.3
问题

BindingResult 被添加为@Valid 参数的下一个参数时,如下所示,继续获取java.lang.StackOverflowError

@RequestMapping(value = "/employees", method = RequestMethod.POST, consumes = "application/json")
public void createEmployee(HttpServletRequest request, @Valid @RequestBody Employee employee, BindingResult result){
    logger.debug("Creating Employee [" + employee.getForename() + " " + employee.getSurname() + "]");
}

如果 BindingResult 方法参数被删除,它可以正常工作。
更新开始
发现问题,StackOverflowError 使用以下代码将BindingResult 实例转换为JSON 时发生:

//log all method arguments   
com.google.gson.Gson gson = new com.google.gson.Gson();
String json = gson.toJson(bindingResultArgFromControllerMethod);

框架代码使用Gson 将方法参数转换为JSON 以进行日志记录。

有没有办法避免/处理这个异常?
更新结束

相关堆栈跟踪:

    Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.StackOverflowError] with root cause

java.lang.StackOverflowError: null
//Repeatattive block start 
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:383)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:378)
//Repeatattive block end 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:155)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
at com.google.gson.Gson.getAdapter(Gson.java:407)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:49)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:106)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
at com.google.gson.Gson.getAdapter(Gson.java:407)

【问题讨论】:

  • 欢迎来到 stackoverflow,请阅读 stackoverflow.com/help/how-to-ask 并用更新的知识更新您的问题。至少在您的 Employee 对象的代码中。
  • 以下链接有一些有效点。请通过它。 dzone.com/articles/spring-31-valid-requestbody
  • 返回类型需要根据本示例进行更改。 public ResponseEntity create(@Valid @RequestBody User user, BindingResult bindingResult) {
  • ` @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity handleMethodArgumentNotValidException( MethodArgumentNotValidException error ) { return parseErrors(error.getBindingResult()); }`
  • @Sanka 在找到异常的根本原因后更新了问题

标签: java spring spring-boot gson spring-validator


【解决方案1】:

根据BindingResult 的API 文档,这只是用户输入浏览器的数据的持有人。此外,BindingResult 的实现可以包含对其他辅助对象的各种引用。根据堆栈跟踪,BindingResult 的当前实现有一个循环引用。

我认为您想对用户输入的数据进行 jsonify。那么你需要做的就是将BindingResulttargetjson化:

com.google.gson.Gson gson = new com.google.gson.Gson();
String json = gson.toJson(bindingResultArgFromControllerMethod.getTarget());

根据method docs,这个target 是:被包装的目标对象,可能是一个bean、一个具有公共字段的对象、一个Map——取决于具体的绑定策略

希望这会有所帮助。

【讨论】:

  • 谢谢,确实有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多