2012-03-14 12 views
17

Sto utilizzando Spring, CXF e Hibernate per creare un servizio Web che esegua query di ricerca su un database esterno che disponga dell'accesso in sola lettura.Come gestire caratteri non validi in un'uscita WS quando si utilizza CXF?

Il problema è che alcune voci nel database hanno caratteri strani (0x2) nei campi di testo e sembra che CXF o la libreria (Aegis?) Che utilizza per elaborare/serializzare gli oggetti restituiti dalla sessione di Hibernate possa Non ci penso:

org.apache.cxf.aegis.DatabindingException: Error writing document.. Nested exception is com.ctc.wstx.exc.WstxIOException: Invalid white space character (0x2) in text to output (in xml 1.1, could output as a character entity) 

Come faccio ad aggirarlo? Idealmente, potrei semplicemente rimuovere quei caratteri, dal momento che non hanno importanza per la mia uscita ... Grazie!

risposta

13
/** 
* From xml spec valid chars:<br> 
* #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]<br> 
* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.<br> 
* @param text The String to clean 
* @param replacement The string to be substituted for each match 
* @return The resulting String 
*/ 
public static String CleanInvalidXmlChars(String text, String replacement) { 
    String re = "[^\\x09\\x0A\\x0D\\x20-\\xD7FF\\xE000-\\xFFFD\\x10000-x10FFFF]"; 
    return text.replaceAll(re, replacement); 
} 

fonte: http://www.theplancollection.com/house-plan-related-articles/hexadecimal-value-invalid-characterheplancollection.com/house-plan-related-articles/hexadecimal-value-invalid-character

+0

che è abbastanza vicino a quello che ho finito per fare al momento, quindi sto marcando come accettato! – elias

+0

Non è sbagliato? Voglio dire, il regexp (escape per java) dovrebbe essere: "[^ \\ x09 \\ x0A \\ x0D \\ x20 - \\ xD7FF \\ xE000 - \\ xFFFD \\ x10000 - \\ x10FFFF]" – greguren

+0

Questo funziona perfettamente per me –

7

Non sono sicuro che questo risponda alla tua domanda, ma ecco cosa ho trovato.

Qui è la classe che genera l'eccezione: http://svn.codehaus.org/woodstox/wstx/trunk/src/java/com/ctc/wstx/api/InvalidCharHandler.java

Sembra che ci sia una discussione sulla questione qui: http://comments.gmane.org/gmane.comp.apache.cxf.user/4373

Forse questo potrebbe si può: È possibile anche impostare un " disable.outputstream.optimization "proprietà su endpoint/bus su true per disabilitare la scrittura diretta sull'outstream e passare sempre attraverso XMLStreamWriter. Dovrebbe realizzare la stessa cosa senza il sovraccarico di avere creato il SAAJModel.

Spero che questo aiuti un po '.

+0

Grazie, amico! Ho già letto questa discussione prima di pubblicare questa domanda. :) Dalla risposta di Dan Kulp, ho capito che forse potevo scrivere un wrapper per XMLStreamWriter per sostituire i personaggi, sto cercando di capire come farlo ... – elias

+0

Se ho capito bene questo è solo uno spazio bianco? Potresti rimuoverlo/sostituirlo nel tuo codice prima di scriverlo su xml? –

+0

Per farlo nel mio codice personale è necessario mettere tutti gli oggetti del database in memoria per elaborarli, prima di inviare la risposta. Non voglio farlo solo a causa di una piccola percentuale di dati problematici. Ho bisogno di mettere il codice per rimuovere i caratteri appena prima che l'associazione dati di CXF scriva l'oggetto sull'output ... Ho letto i documenti di CXF per vedere come procedere. – elias

0

La risposta top-rated non ha funzionato per me, come la data codifica Unicode è stata respinta. Con un lieve alterazione tuttavia, è visualizzato il comportamento desiderato:

public static String CleanInvalidXmlChars(String text, String replacement) { 
    String re = "[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\u0001\\u0000-\\u0010\\uFFFF]"; 
    return text.replaceAll(re, replacement); 
} 
+0

Questa regex accetta tutti i caratteri nell'intervallo 0x0-0x10. Molti di questi non sono validi in XML. – Erik

0

Per ottenere il comportamento desiderato ed evitare eccezioni di essere gettato, si dovrà estendere le Woodstoks predefinite com.ctc.wstx.stax.WstxOutputFactory con i propri di, che dovrebbe solo per sovrascrivere la proprietà com.ctc.wstx.outputInvalidCharHandler con un'istanza di com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler. Questo gestore prende come argomento costruttore il carattere sostitutivo per quelli non validi. Con la tua istanza in mano, crea un file chiamato META-INF/services/javax.xml.stream.XMLOutputFactory e inserisci al suo interno solo il nome completo dell'implementazione (assicurati che sia collocato all'interno della directory META-INF/services nel jar risultante).

Potete trovare ulteriori dettagli here.

HTH!

+1

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - [Dalla recensione] (/ recensione/post di bassa qualità/18055529) – daniele3004

+0

Aggiornato di conseguenza la risposta, grazie per i suggerimenti. – cristianoms

Problemi correlati