2009-03-12 1 views
3

Ich habe einen REST-Webservice, der auf POST-Anfragen wartet und eine XML-Payload vom Client erhält und sie zunächst als InputStream speichert, dh auf dem Repräsentationsobjekt, das getStream aufgerufen werden kann().Die beste Möglichkeit, einen InputStream in Bezug auf Persistenz und XML zu verwenden

Ich möchte die im InputStream enthaltene XML verwenden und ich bin der Meinung, dass es klug wäre, sie zu bestehen, so dass ich die Daten mehrmals abfragen kann - sobald Sie das gelesen haben, wird das Objekt null. Also habe ich darüber nachgedacht, den InputStream in eine Zeichenkette umzuwandeln. Dies ist keine gute Idee, da DocumentBuilder.parse() aus javax.xml.parsers Bibliothek werden Sie nur passieren lassen:

  • Inputstreams
  • URLs
  • Dateien
  • SAX InputSources

keine Zeichenketten.

Was sollte ich hier eigentlich mit InputStreams in Bezug auf das Parsen von XML tun? Bedenkt, ich werde diese XML in zukünftigen Prozessen durch den Code erneut abfragen wollen.

Antwort

2

Wenn Sie einen InputStream haben und ihn als XML-Dokument verwenden möchten, warum analysieren Sie ihn dann nicht einfach und geben das Document-Objekt weiter? Wenn Sie dieses Objekt beibehalten möchten, verwenden Sie einen Serializer, um es als Text zurückzuschreiben.

Wie ich in meinem Kommentar zu Tom Hawtin bemerkt habe, ist die Kodierung sehr wichtig im Umgang mit XML. Anstatt hier einen langen Beitrag zu verfassen, der vielleicht Ihre spezifische Situation verfehlt, hier ist eine article, die ich geschrieben habe.

Edit: eigentlich, da mein Artikel nicht speziell über Web-Services spricht, sollte ich hier ein wenig reinschauen. Es gibt zwei Stellen, an denen die Inhaltscodierung angegeben werden kann: im XML-Prolog oder in der Antwort-Kopfzeile Content-Type. Gemäß der XML-Spezifikation ist die erste die, die Sie verwenden möchten, und es ist, was der Parser verwenden wird. In den meisten Fällen spielt das keine Rolle: Ein Webservice, der von einer Person eingerichtet wird, die die Spezifikation nicht kennt, verwendet normalerweise einen Text/XML ohne Zeichensatzspezifikation (was falsch ist, aber wahrscheinlich keinen Schaden verursacht). Wenn sie die Dinge richtig machen, geben sie application/xml mit utf-8 encoding an. Sie sollten jedoch überprüfen, was Sie erhalten, damit Sie nicht mit einer seltsamen Codierung enden, die der Parser nicht verarbeiten kann.

+0

Ich denke, die Übergabe des Document-Objekts scheint hier die schmerzloseste Sache zu sein - und etwas offensichtliches - Entschuldigung, ich glaube nicht, dass mein Gehirn heute morgen überhaupt funktionierte! – Vidar

-2

java.io.StringReader können Sie verwenden.

Sie könnten die Daten in einem byte[] speichern und dann mit ByteArrayInputStream lesen. Wenn es besonders groß ist, möchten Sie vielleicht die Komprimierung in Betracht ziehen. Dies kann mit GzipInputStream ausgelesen werden, die oft in eine BufferedInputStream verpackt werden sollte.

+0

-1, weil Sie NIEMALS XML mit einem StringReader lesen möchten, es sei denn, Sie erhalten die Kodierung extern (was in Webdiensten der Fall sein kann). – kdgregory

+0

Entschuldigung, machen Sie das irgendein Leser – kdgregory

+0

@ kdgregory - Ist das, weil das Ende der Zeile zwischen den Kodierungen variieren kann? –

0

Ich denke, Sie sollten in einige Strukturen besser geeignet für die Bewahrung von Kodierungen (dh mehr Kodierung Agnostiker) suchen. Berücksichtigen Sie bei Strukturen auf niedriger Ebene byte[] (aber seien Sie bei der Speicherfreigabe vorsichtig!) Oder versuchen Sie, einen Datentyp zu erstellen, der Ihren Anforderungen entspricht.

Sie konnten die InputStream in eine ByteArrayOutputStream (unter Verwendung eines der read() Methoden) und extrahieren Sie die byte[] von there lesen.

1

Wenn wir Persistenz sprechen, reden wir im Allgemeinen davon, sie auf Disk oder andere Medien zu schreiben. Da ist eine Leistungseinbuße, und Sie müssen über Speicherplatzprobleme nachdenken. Sie sollten das gegen den Wert abwägen, dieses XML langfristig zu nutzen.

Wenn Sie nur darüber reden, es im Speicher zu halten (was wie das klingt, was Sie fragen), dann könnten Sie ein Byte-Array zuweisen und das Ganze in das Byte-Array lesen. Sie können ByteArrayInputStream verwenden, um diesen Stream zu lesen und erneut zu lesen.

Die Kosten mit dem ist zweifach. Zuerst halten Sie eine Kopie im Speicher, und Sie müssen dies gegen Ihre Skalierbarkeitsanforderungen abwägen. Zweitens ist das Parsen von XML etwas teuer, daher ist es am besten, wenn möglich, es nur einmal zu parsen und das Ergebnis in einem Objekt zu speichern.

Edit:

zuzuweisen und das Byte-Array zu lesen, können Sie oft (aber nicht immer) verlassen sich auf die Input verfügbar() -Methode, Ihnen zu sagen, wie viel zuzuteilen. und wickle den InputStream mit einem DataInputStream, so dass du readFully() aufrufen kannst, um das Ganze mit einem Aufruf in das Byte-Array zu saugen.

Bearbeiten wieder:

lesen Steen Kommentar unten. Er hat Recht, dass es eine schlechte Idee ist, in diesem Fall verfügbares() zu verwenden.

+0

Ich bin eine Live-Umgebung, _never_ Verwendung verfügbar() als Mittel, um die "Größe" des Streams. Verdammt, du solltest es nicht einmal in deinem Hinterhof benutzen;) – Steen

+0

Benutze stattdessen die read() wie in meinem ausgearbeiteten Post irgendwo auf dieser Seite beschrieben (ich kann mich nie an Stackoverflows Floating-Antworten gewöhnen) – Steen

+0

Es ist in Ordnung gegen FileInputStream zu verwenden , aber es ist problematisch, wenn es gegen netzwerkgestützte Streams verwendet wird. Ich habe meine Zurückhaltung, es in diesem Fall zu verwenden, nicht stark genug angegeben. –

1

Ich würde empfehlen, die Apache Commons IO Bibliothek zu verwenden. Die Klasse IOUtils enthält viele bequeme Methoden zum Konvertieren von InputStreams in String und umgekehrt.

+0

Guter Rat. Speichert ein paar Zeilen über das Lesen selbst, wie ich in meiner Antwort beschrieben habe. –

+0

Aber ich glaube nicht, dass ich es in eine Zeichenkette umwandeln sollte - also würde IOUtils in diesem Fall von Nutzen sein? – Vidar

+0

Sie sollten nicht in eine Zeichenfolge konvertieren, wenn Sie die Codierung nicht kennen. IOUtils gibt Ihnen jedoch auch einen TeeInputStream, sodass Sie eine Kopie als Byte speichern können. – kdgregory

0

Wenn Sie das XML mehrmals verwenden möchten, warum analysieren Sie es nicht einmal aus dem InputStream (was ist die schwere Arbeit), und halten Sie dann an das Dokument zurückgegeben?

Verwandte Themen