Конец потока XML через соединение JSSE? - PullRequest
2 голосов
/ 04 ноября 2008

У меня есть сервер Java, который принимает соединения SSL с использованием JSSE и использует простой формат сообщения XML внутри потока. Я хотел бы, чтобы сервер прочитал полное сообщение и затем отправил ответ. Это оказывается довольно сложно, потому что org.xml.sax.XMLReader хочет прочитать весь поток и затем вызвать close (). Я знаю, это кажется странным, но в Java 6 с поставщиком JSSE Sun это действительно закрывает оба конца SSLSocket, поэтому никакое сообщение не может вернуться назад. Я пытался использовать метод Socket shutdownOutput () на стороне клиента, но это не поддерживается JSSE.

Мое решение состояло в том, чтобы передать InputStream, заключенный в пользовательский класс, который молча игнорирует запросы на закрытие и указывает, что поток закрывается, когда он встречает первую пустую строку. Это ограничивает XML за пределы того, что обычно допустимо, но клиент может легко отфильтровать пустые строки во входных данных при необходимости. Есть ли лучшее решение?

Ответы [ 2 ]

1 голос
/ 06 ноября 2008

Поскольку каждый XML-документ имеет только один корневой узел. Итак, отсканируйте конец этого узла и закройте поток после.

1 голос
/ 05 ноября 2008

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

Решение, позволяющее избежать чтения до конца входного потока, заключается в том, чтобы как-то разграничить входное сообщение. Например, вы можете отправить длину сообщения перед сообщением, затем прочитать все сообщение из потока в буфер, затем проанализировать буфер с помощью XMLReader или создать специальный InputStream, который принимает свой конец, который достигает своего конца после указанного количества данные. Или вы можете добавить специальный разделитель в поток после сообщения, а затем создать специальный InputStream, который достигает своего конца, когда базовый поток создает разделитель.

...