如何解决Spring Boot-Jackson EntityNotFoundException返回200而不是500响应
即使我已将其指定为在遇到此异常时在处理程序(HttpStatus.INTERNAL_SERVER_ERROR)中返回500,异常处理程序仍将返回200响应。
我正在使用Spring Boot v1.5.4.RELEASE。
我正在调用Spring Boot服务并返回JSON对象。我正在使用自定义异常处理程序。
在反序列化期间发生EntityNotFoundException时,它不返回500响应,而是返回200响应并将错误嵌入到主体输出中。这是由于数据错误导致的,因为外键无效,因此在数据库中找不到ManyToOne关系。
@Entity
@Table(name = "PARENT_ENTITY")
public class ParentEntity {
@JsonView({MyViews.ParentEntity.class})
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="CHILD_KEY")
protected ChildEntity childKey;
}
如何做到这一点,以便该服务返回500响应而不是200?
代码示例:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler{
@ExceptionHandler(EntityNotFoundException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR,reason = "INTERNAL_SERVER_ERROR")
protected ResponseEntity<Object> handleEntityNotFoundException(EntityNotFoundException ex) {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR);
apiError.setMessage(ex.getMessage());
apiError.setStackTrace(StringUtil.jsonescapeNewlines(ExceptionUtils.getStackTrace(ex)));
return new ResponseEntity<>(apiError,apiError.getStatus())
}
}
服务的示例输出:
响应码:200
身体:
[
{
"field1": "data1","childEntity": {
"childKey":"100100"
}
},{
"field1":"data2"
"childEntity": {
"childKey": {
"status": "INTERNAL_SERVER_ERROR","message": "Could not write JSON: Unable to find com.test.entity.ChildEntity with id 123456; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unable to find com.test.entity.ChildEntity with id 123456; (through reference chain: java.util.ArrayList[40]->com.test.entity.ParentEntity[\"childKey\"])","stackTrace": "org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Unable to find com.test.entity.ChildEntity with id 123456 ; nested exception is com.fasterxml.jackson.databind.JsonMappingException: ... org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:299)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:106)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
at org.springframework.web.servlet.mvc.method.annotation.ServletinvocableHandlerMethod.invokeAndHandle(ServletinvocableHandlerMethod.java:113)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.dispatcherServlet.dodispatch(dispatcherServlet.java:967)
at org.springframework.web.servlet.dispatcherServlet.doService(dispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:751)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:137)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:460)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:120)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:217)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:81)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3456)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3422)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:323)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2280)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2196)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2174)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1632)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:256)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unable to find com.test.entity.ChildEntity with id 123456;
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:348)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:343)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:698)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:112)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:416)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1425)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:951)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:292)
... 58 more\
Caused by: javax.persistence.EntityNotFoundException: Unable to find com.test.entity.ChildEntity with id 123456;
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:144)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:242)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:159)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
at com.test.entity.ParentEntity_$$_jvst2de_11.getChildKey(ParentEntity_$$_jvst2de_11.java)
at com.test.entity.ParentEntity.getChildKey(ParentEntity.java:887)
at sun.reflect.GeneratedMethodAccessor5472.invoke(UnkNown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:664)
at com.fasterxml.jackson.databind.ser.impl.FilteredBeanPropertyWriter$SingleView.serializeAsField(FilteredBeanPropertyWriter.java:69)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:690)
... 66 more\
","headers": null
}
#note:我并没有仅仅为了这个例子而切断它。在实际的json响应中将其切断,导致json格式错误。
解决方法
我想知道您的请求是否由同一个异常处理程序处理。
您已将用户消息设置为“数据问题”,但输出响应将其显示为null。
apiError.setUserMessage("Data issue:" + ex.getMessage());
//based on your code it should have at least "Data issue:"
"userMessage": null,
请确保验证您发布的代码是否作为此请求的一部分被调用。当然,您可以添加一条日志消息以确认相同。如果您能够在本地复制问题,则可以保留一个断点并确认是否调用了相同的异常处理程序。
,您可以通过在查询中进行内部联接来避免未找到实体错误。下面的示例使用本机查询格式。这更像是一种解决方法,但足以解决我的情况。我现在将其标记为答案。
select pe.* from PARENT_ENTITY pe
inner join CHILD_ENTITY ce on pe.CHILD_KEY = ce.rowid_org_cust
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。