Как передать тип SQLXML для просмотра в Spring MVC?

В моем контроллере веб-приложения я получаю результаты из базы данных, которые имеют тип java.sql.SQLXML. Я хочу передать его в представление, которое будет возвращено дословно (как XML).

Проблема в том, что данные, связанные с SQLXML, высвобождаются, как только я покидаю вызов JdbcTemplate. Как же мне передать данные в представление с помощью модели?


person Horacy Oliwka    schedule 03.04.2010    source источник


Ответы (1)


Самое простое решение — прочитать данные из объекта SQLXML перед выходом из вызова JdbcTemplate и вернуть данные в виде byte[], String, DOM или чего-то еще.

Если это нецелесообразно (например, данные слишком велики), вам нужно будет предпринять шаги, чтобы сохранить соединение открытым за рамками вызова JdbcTemplate, а это означает использование транзакций. Если открыть транзакцию перед вызовом JdbcTemplate, соединение будет привязано к этой транзакции и будет оставаться открытым, пока вы не закроете транзакцию. К сожалению, чтобы держать его открытым достаточно долго для визуализации вида, требуется некоторая гимнастика.

Предполагая, что у вас еще нет настроенных транзакций, вам понадобится bean-компонент DataSourceTransactionManager в вашем контексте. Затем вы можете написать HandlerInterceptor для управления транзакцией, удерживая ее открытой достаточно долго, чтобы представление отобразилось. Spring не предоставляет удобных перехватчиков для этого из коробки, как это делается с JPA/Hibernate/и т. д., поэтому вам нужно будет написать свой собственный 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);
    }
}

Затем вы настроить этот перехватчик для вызова, когда запрос вызывает ваш контроллер + представление.

person skaffman    schedule 03.04.2010