Java 每个请求一个事务-servlet响应提交得太早

Java 每个请求一个事务-servlet响应提交得太早,java,spring,tomcat,transactions,spring-boot,Java,Spring,Tomcat,Transactions,Spring Boot,我试图在spring引导应用程序中为每个请求实现一个事务。 我有一个具有最高优先级顺序的过滤器,它可以打开事务,让其他过滤器和应用程序的服务完成它们的工作,并提交事务。但是,如果提交失败,servlet响应已经编写并提交(带有成功代码),我不能修改它的状态和消息体来提供有关错误的信息 我需要servlet响应在我的过滤器中是可修改的,但是有东西提交了它 我已经禁用了jackson提交,但就在最后一个筛选器(WsFilter)之后,消息还是提交了。缓冲区大小尽可能大。我猜嵌入式tomcat默认在W

我试图在spring引导应用程序中为每个请求实现一个事务。 我有一个具有最高优先级顺序的过滤器,它可以打开事务,让其他过滤器和应用程序的服务完成它们的工作,并提交事务。但是,如果提交失败,servlet响应已经编写并提交(带有成功代码),我不能修改它的状态和消息体来提供有关错误的信息

我需要servlet响应在我的过滤器中是可修改的,但是有东西提交了它

我已经禁用了jackson提交,但就在最后一个筛选器(WsFilter)之后,消息还是提交了。缓冲区大小尽可能大。我猜嵌入式tomcat默认在WsFilter之后提交

我还尝试使用包装器并禁止刷新,直到在我的事务过滤器中将布尔标志设置为true,但出现空指针异常-coyoteResponse为空


如何使响应保持未提交状态

我最终使用了ContentCachingResponseWrapper。这样,我的事务过滤器之后的所有过滤器都使用包装器而不是原始响应。由于原始响应未被触及,因此未提交。过滤器关闭事务后,我调用responseWrapper.copybodytoreresponse()将包装中的所有数据“刷新”到原始响应

通常,代码如下所示:

// create a transaction
// create a wrapper
chain.doFilter(request, responseWrapper);
// end the transaction
responseWrapper.copyBodyToResponse();

我最终使用了ContentCachingResponseWrapper。这样,我的事务过滤器之后的所有过滤器都使用包装器而不是原始响应。由于原始响应未被触及,因此未提交。过滤器关闭事务后,我调用responseWrapper.copybodytoreresponse()将包装中的所有数据“刷新”到原始响应

通常,代码如下所示:

// create a transaction
// create a wrapper
chain.doFilter(request, responseWrapper);
// end the transaction
responseWrapper.copyBodyToResponse();

您需要确保在所有提交成功之前未向ServletResponse写入任何内容共享包装器代码您需要确保在所有提交成功之前未向ServletResponse写入任何内容共享包装器代码