2010-04-03 3 views
0

Dans mon contrôleur webapp, j'obtiens des résultats de la base de données, qui sont de type java.sql.SQLXML. Je veux le transmettre à la vue pour être retourné mot pour mot (comme XML).Comment passer le type SQLXML à afficher dans Spring MVC?

Le problème est que les données associées à SQLXML sont libérées dès que je quitte l'appel JdbcTemplate. Comment puis-je transmettre les données à la vue en utilisant un modèle?

Répondre

0

La solution la plus simple est de lire les données de l'objet SQLXML avant de quitter l'invocation JdbcTemplate, et renvoyer les données en tant que byte[], String, DOM ou autre. Si ce n'est pas pratique (par exemple si les données sont trop volumineuses), vous devrez prendre des mesures pour que la connexion reste ouverte au-delà de la portée de l'appel JdbcTemplate, ce qui signifie utiliser des transactions. En ouvrant une transaction avant d'appeler le JdbcTemplate, la connexion devient liée à cette transaction et restera ouverte jusqu'à la clôture de la transaction. Malheureusement, le garder ouvert assez longtemps pour que la vue soit rendue exige une certaine gymnastique.

En supposant que vous n'avez pas encore configuré les transactions, vous aurez besoin d'un bean DataSourceTransactionManager dans votre contexte. Vous pouvez alors écrire un HandlerInterceptor pour gérer la transaction, en le laissant ouvert suffisamment longtemps pour que la vue soit rendue. Le printemps ne fournit pas des intercepteurs pratiques pour ce hors-the-box, comme il le fait avec JPA/Hibernate/etc, vous aurez donc besoin d'écrire votre propre HandlerInterceptor, quelque chose comme ceci:

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

Vous puis configure this interceptor à appeler lorsqu'une requête appelle votre contrôleur + vue.

Questions connexes