在我的 webapp 控制器中,我从 db 获取结果,这些结果是java.sql.SQLXML
. 我想将它传递给要逐字返回的视图(作为 XML)。
问题是,一旦我离开 JdbcTemplate 调用,与 SQLXML 关联的数据就会被释放。那么我应该如何使用模型将数据传递给视图?
在我的 webapp 控制器中,我从 db 获取结果,这些结果是java.sql.SQLXML
. 我想将它传递给要逐字返回的视图(作为 XML)。
问题是,一旦我离开 JdbcTemplate 调用,与 SQLXML 关联的数据就会被释放。那么我应该如何使用模型将数据传递给视图?
SQLXML
最简单的解决方案是在离开调用之前从对象中读取数据JdbcTemplate
,并将数据作为byte[]
、String
、 DOM 或其他形式返回。
如果这不切实际(例如数据太大),那么您需要采取措施在JdbcTemplate
调用范围之外保持连接打开,这意味着使用事务。通过在调用之前打开事务JdbcTemplate
,连接将绑定到该事务,并将保持打开状态,直到您关闭事务。不幸的是,保持它打开足够长的时间以渲染视图需要一些体操。
假设您还没有设置事务,那么您将需要一个DataSourceTransactionManager
bean 在您的上下文中。然后,您可以编写一个HandlerInterceptor
来管理事务,使其保持打开足够长的时间以呈现视图。Spring 没有为这种开箱即用的方式提供方便的拦截器,就像 JPA/Hibernate/etc 一样,因此您需要编写自己的拦截器,HandlerInterceptor
如下所示:
public class TransactionInterceptor extends HandlerInterceptorAdapter {
private PlatformTransactionManager txManager;
public void setTxManager(PlatformTransactionManager txManager) {
this.txManager = txManager;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
TransactionStatus tx = txManager.getTransaction(new DefaultTransactionDefinition());
request.setAttribute("tx", tx);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
TransactionStatus tx = (TransactionStatus) request.getAttribute("tx");
txManager.commit(tx);
}
}
然后,您配置此拦截器以在请求调用您的控制器 + 视图时调用。