Domanda

Ho un servizio web REST che ascolta le richieste POST e afferra un payload XML dal client e lo memorizza inizialmente come InputStream, cioè sull'oggetto Rappresentazione che puoi chiamare getStream () .

Voglio utilizzare l'XML contenuto in InputStream e sto cominciando a pensare che sarebbe saggio persisterlo, così posso interrogare i dati più volte - come una volta letto, l'oggetto diventa nullo. Quindi ho pensato di convertire InputStream in una stringa. Questa non è una buona idea in quanto DocumentBuilder.parse () dalla libreria javax.xml.parsers ti consentirà solo di passare:

  • InputStreams
  • File
  • URL
  • Fonti di input SAX

non stringhe.

Cosa dovrei davvero fare qui con InputStreams in relazione all'analisi di XML da esso? Tenendo presente che vorrò ri-interrogare quell'XML nei processi futuri con il codice.

È stato utile?

Soluzione

Se si dispone di un InputStream e si desidera utilizzarlo come documento XML, perché non lo si sta semplicemente analizzando e passando l'oggetto Document? Se vuoi persistere su questo oggetto, usa un serializzatore per riscriverlo come testo.

Come ho notato nel mio commento a Tom Hawtin, la codifica è molto importante quando si ha a che fare con XML. Piuttosto che scrivere qui un lungo post che potrebbe non farti capire la tua situazione specifica, ecco un articolo che ho scritto.

Modifica: in realtà, dal momento che il mio articolo non parla specificamente di servizi Web, dovrei approfondire un po 'qui. Esistono due posizioni in cui è possibile specificare la codifica del contenuto: nel prologo XML o nell'intestazione della risposta Content-Type . Secondo le specifiche XML, la prima è quella che si desidera utilizzare ed è ciò che verrà utilizzato dal parser. Nella maggior parte dei casi, ciò non importa: un servizio web creato da una persona che non conosce la specifica utilizzerà in genere un testo / xml senza una specifica del set di caratteri (che è errata ma probabilmente non causerà danni). Se fanno le cose correttamente, specificheranno application / xml, con codifica utf-8. Tuttavia, dovresti verificare ciò che stai ricevendo, in modo da non finire con una strana codifica che il parser non è in grado di gestire.

Altri suggerimenti

Vorrei consigliare di utilizzare la libreria Apache Commons IO . La classe IOUtils contiene molti metodi utili per converte InputStreams in String e viceversa.

Generalmente, quando parliamo di persistenza, stiamo parlando di scriverlo su disco o altri media. C'è un impatto sulle prestazioni lì e devi pensare alle preoccupazioni relative allo spazio su disco. Ti consigliamo di metterlo a confronto con il valore di avere quell'XML a lungo termine.

Se stai solo parlando di tenerlo in memoria (che suona come quello che stai chiedendo), allora potresti allocare un array di byte e leggere tutto nell'array di byte. Puoi usare ByteArrayInputStream per leggere e rileggere quel flusso.

Il costo è duplice. Innanzitutto, ne stai conservando una copia in memoria e devi valutarla rispetto ai tuoi requisiti di scalabilità. In secondo luogo, analizzare XML è alquanto costoso, quindi è meglio analizzarlo una sola volta, se possibile, e salvare il risultato in un oggetto.

Modifica:

Per allocare e leggere l'array di byte, puoi spesso (ma non sempre) fare affidamento sul metodo disponibile () di InputStream per dirti quanto allocare. e avvolgi InputStream con un DataInputStream in modo da poter chiamare readFully () per aspirare il tutto nell'array di byte con una chiamata.

Modifica di nuovo:

Leggi il commento di Steen di seguito. Ha ragione nel dire che è una cattiva idea usare available () in questo caso.

Se si desidera utilizzare più volte l'XML, perché non analizzarlo una volta da InputStream (che è un lavoro pesante), e quindi conservare il documento restituito?

Penso che dovresti esaminare alcune strutture più adatte alla conservazione delle codifiche (ad es. più codifica agnostica). Per le strutture di basso livello, considera byte [] (ma fai attenzione con la deallocazione della memoria!) Oppure potresti provare a progettare un tipo di dati adatto alle tue esigenze.

Puoi leggere InputStream in un ByteArrayOutputStream (utilizzando uno dei read () metodi) ed estrai il byte [] da .

java.io.StringReader ti permetterà di usare InputSource .

Potresti voler archiviare i dati in un byte [] e quindi leggere con ByteArrayInputStream . Se è particolarmente grande, potresti prendere in considerazione la compressione. Questo può essere letto con GzipInputStream , che spesso dovrebbe essere racchiuso in un BufferedInputStream .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top