作者: whooyun发表于: 2025-02-12 09:27
技术背景:
springboot+openfeign接口,服务消费者调用服务提供者时,服务接口提供者提示以下信息
05:39:31.667 [tomcat-handler-40] [1;31mERROR[0;39m [36mc.a.w.h.GlobalExceptionHandler[0;39m - [respondWithError,137] - Exception occurred:
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.OutOfMemoryError: try enabling LargeObject feature instead
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1104)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at java.base/java.lang.VirtualThread.run(VirtualThread.java:329)
Caused by: java.lang.OutOfMemoryError: try enabling LargeObject feature instead
at com.alibaba.fastjson2.JSONWriterUTF8.ensureCapacity(JSONWriterUTF8.java:2122)
at com.alibaba.fastjson2.JSONWriterUTF8.writeStringLatin1(JSONWriterUTF8.java:505)
at com.alibaba.fastjson2.JSONWriterUTF8JDK9.writeString(JSONWriterUTF8JDK9.java:22)
at com.alibaba.fastjson2.writer.ObjectWriterImplLocalDateTime.write(ObjectWriterImplLocalDateTime.java:142)
at com.alibaba.fastjson2.writer.FieldWriterObjectFinal.write(FieldWriterObjectFinal.java:89)
at com.alibaba.fastjson2.writer.ObjectWriterAdapter.write(ObjectWriterAdapter.java:308)
at com.alibaba.fastjson2.writer.ObjectWriterImplList.write(ObjectWriterImplList.java:364)
at com.alibaba.fastjson2.writer.OWG_1_4_R.write(Unknown Source)
at com.alibaba.fastjson2.JSON.writeTo(JSON.java:3619)
at com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter.writeInternal(FastJsonHttpMessageConverter.java:138)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:235)
at com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter.write(FastJsonHttpMessageConverter.java:86)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:297)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:192)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
原因:
fastjson2基于性能考虑,限制了bean转json时嵌套的层级和数据量大小
解决方案:
服务接口提供者对返回值进行json处理时,开放大对象特性
JSONArray.from(cabinCollectOrders, JSONWriter.Feature.LargeObject)
例如
fun queryOrderByScanTimeAndSite(
startDate: String?,
endDate: String?,
siteId: Long?,
providerId: Int?
): JSONArray {
val cabinCollectOrders =
collectOrderMapper.queryCabinCollectOrderByScanTimeAndSite(startDate, endDate, siteId, providerId)
if (cabinCollectOrders.isEmpty()) {
return JSONArray()
}
return JSONArray.from(cabinCollectOrders, JSONWriter.Feature.LargeObject)
}