如何在 Spring MVC 中传递 SQLXML 类型来查看?

发布于 2024-08-27 18:22:38 字数 169 浏览 6 评论 0原文

在我的 web 应用程序控制器中,我从数据库获取结果,其类型为 java.sql.SQLXML。 我想将它传递给要逐字返回的视图(作为 XML)。

问题是,一旦我离开 JdbcTemplate 调用,与 SQLXML 关联的数据就会被释放。那么我应该如何使用模型将数据传递到视图呢?

In my webapp controller I'm getting results from the db, which are of type java.sql.SQLXML.
I want to pass it to the view to be returned verbatim (as XML).

The problem is, the data associated with SQLXML is released as soon as I leave JdbcTemplate call. How then should I pass the data to the view using a model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羞稚 2024-09-03 18:22:38

最简单的解决方案是在离开 JdbcTemplate 调用之前从 SQLXML 对象中读取数据,并将数据作为 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);
    }
}

:然后 配置当请求调用您的控制器+视图时,将调用此拦截器

The simplest solution is to read the data out of the SQLXML object before you leave the JdbcTemplate invocation, and return the data as a byte[], String, DOM or whatever.

If that's not practical (e.g. the data is too large), then you'll need to take steps to keep the connection open beyond the scope of the JdbcTemplate call, and that means using transactions. By opening a transaction before calling JdbcTemplate, the connection becomes bound to that transaction, and will be kept open until you close the transaction. Unfortunately, keeping it open long enough for the view to be rendered requires some gymnastics.

Assuming you don't have transactions already setup, then you'll need a DataSourceTransactionManager bean in your context. You could then write a HandlerInterceptor to manage the transaction, keeping it open long enough for the view to render. Spring doesn't provide convenient interceptors for this out-of-the-box, like it does with JPA/Hibernate/etc, so you'll need to write your own HandlerInterceptor, something like this:

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);
    }
}

You then configure this interceptor to be invoked when a request calls your controller + view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文