2008-11-04 8 views
2

J'ai un serveur Java qui accepte les connexions SSL en utilisant JSSE et utilise un simple format de message XML dans le flux. Je voudrais que le serveur lise un message complet et envoie une réponse. Cela s'avère assez difficile car org.xml.sax.XMLReader veut lire le flux entier et ensuite appeler close(). Je sais que cela semble étrange, mais en Java 6 avec le fournisseur Sun JSSE cela ferme vraiment les deux extrémités de la SSLSocket, donc aucun message ne peut revenir en arrière. J'ai essayé d'utiliser la méthode shutdownOutput() de Socket du côté client, mais cela n'est pas supporté par JSSE.Fin d'un flux XML sur une connexion JSSE?

Ma solution était de passer un InputStream enveloppé dans une classe personnalisée qui ignore silencieusement les demandes de fermeture et indique que le flux est fermé lorsqu'il rencontre la première ligne vide. Cela contraint le XML au-delà de ce qui est normalement valide, mais le client peut facilement filtrer les lignes vides dans l'entrée si nécessaire. Y a-t-il une meilleure solution?

Répondre

1

Comment votre client sait-il qu'un message complet a été lu? S'il doit être lu jusqu'à ce que le flux d'entrée atteigne sa fin, alors, par définition, vous ne pourrez plus rien lire du flux après coup. Sur une deuxième note, invoquer close() sur le flux d'entrée ne doit pas fermer le socket. Êtes-vous sûr que le socket est fermé lorsque vous appelez close() sur le flux d'entrée? Peut être que la connexion est (incorrectement) fermée par l'homologue lorsqu'elle remarque que son flux de sortie (votre flux d'entrée) a été fermé.

Une solution qui évite la lecture jusqu'à la fin du flux d'entrée consiste à délimiter le message d'entrée d'une manière ou d'une autre. Par exemple, vous pouvez envoyer la longueur du message avant le message, puis lire le message entier du flux dans un tampon, puis analyser le tampon à l'aide de XMLReader ou créer un InputStream spécial qui prend fin après la quantité spécifiée de Les données. Ou vous pouvez ajouter un délimiteur spécial dans le flux après le message, puis vous créez un InputStream spécial atteint sa fin lorsque le flux sous-jacent produit le délimiteur.

1

Étant donné que chaque document XML a un seul nœud racine. Donc, scannez la fin de ce noeud et fermez le flux après.