Forum » Programiranje » Web services - Neveljavni karakterji v XML
Web services - Neveljavni karakterji v XML
MrStein ::
Keywords: web services, Java, SOAP, XML
1.) Kdo najde bug v spodnji (Java) kodi?
(gre za Contract Last oziroma code first pristop pisanju Web Service aplikacije/serverja, torej framework bo iz te Java kode naredil WSDL in vse potrebno za implementacijo delujočega web servisa)
2.) Kako fixati, ne da bi celi Apache CXF framework reimplementiral?
Kaki drug framework (za Java), ki to pravilno hendla, je dobrodošel. (Axis ga tudi ne, kolikor vem)
1.) Kdo najde bug v spodnji (Java) kodi?
(gre za Contract Last oziroma code first pristop pisanju Web Service aplikacije/serverja, torej framework bo iz te Java kode naredil WSDL in vse potrebno za implementacijo delujočega web servisa)
@WebMethod(operationName = "test1") @WebResult(name = "test1", targetNamespace = "http://test.example.org/") public String test1() { char backspace = '\u0008'; // backspace je ločena spremenljivka le zato, da je lažje prebrati kodo return "1 + 1 = 3"+backspace+"2"; }
2.) Kako fixati, ne da bi celi Apache CXF framework reimplementiral?
Kaki drug framework (za Java), ki to pravilno hendla, je dobrodošel. (Axis ga tudi ne, kolikor vem)
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
- spremenil: MrStein ()
Ktj ::
Če je možno spremeniti v byte[], potem nekaj v temu smislu:
... String result ="1 + 1 = 3" + backspace + "2"; return result.getBytes(StandardCharsets.UTF_8); ...
MrStein ::
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
MrStein ::
Če je možno spremeniti v byte[], potem nekaj v temu smislu:
...
String result ="1 + 1 = 3" + backspace + "2";
return result.getBytes(StandardCharsets.UTF_8);
...
In bi tudi interface spremenil?
Kaj pa če gre za objekt, ki ima na ducate spremenljivk tipa String? A gremo celi business model spremeniti (in se odreč kupu priročnih funkcij za delo s String-i)?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
kunigunda ::
Če je možno spremeniti v byte[], potem nekaj v temu smislu:
...
String result ="1 + 1 = 3" + backspace + "2";
return result.getBytes(StandardCharsets.UTF_8);
...
In bi tudi interface spremenil?
Kaj pa če gre za objekt, ki ima na ducate spremenljivk tipa String? A gremo celi business model spremeniti (in se odreč kupu priročnih funkcij za delo s String-i)?
Backspace nima neke funkcionalnosti. Je zgolj char kot vsi drugi. Funkcije kot so print ipd potem predelajo izpis (pobrise znak levo), pa se to izven IDE (IDE-ji radi po svoje potem
nardijo izpis). Tko da ce si mislu da ti bo vrnu v webservice response 1+1=2, ti ne bo :)
MrStein ::
Seveda, vrniti mora točno to, kar piše.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
MrStein ::
Mogoče je backspace bil napačen znak za primer.
Boljši bi bil Form Feed (\u000c) ali Escape (\u000b).
Torej ta vrstica v prvem sporočilu bi bila:
Še malo referenc:
XML @ Wikipedia
ASCII @ Wikipedia
SOAP @ Wikipedia
Boljši bi bil Form Feed (\u000c) ali Escape (\u000b).
Torej ta vrstica v prvem sporočilu bi bila:
char backspace = '\u000b'; // ni backspace ampak escape
Še malo referenc:
XML @ Wikipedia
ASCII @ Wikipedia
SOAP @ Wikipedia
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
kunigunda ::
Isto. To so nonescaped znaki.
Ce hoces ven dobiti v stilu &#.. bos moral sam konvertirati. &<> ipd ti bo pa sam v html konvertiru & itd
MrStein ::
Zakaj bi sam konvertiral?
Potem bo framework še enkrat "konvertiral" in bo na koncu rezultat:
<ns2:test1>1 + 1 = 3&#x000b2</ns2:test1>
(pišem kot navaden tekst, ker forum včasih zameša kodo)
Potem bo framework še enkrat "konvertiral" in bo na koncu rezultat:
<ns2:test1>1 + 1 = 3&#x000b2</ns2:test1>
(pišem kot navaden tekst, ker forum včasih zameša kodo)
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
MrStein ::
Aja, še odgovor na vprašanje 1: Rezultat kode je invalid XML, ki ga bo vsak klient zavrnil z napako, ker znaki s kodo pod 0x20 so ilegalni v XML. (razen TAB, NL in CR, glej prejšnji link)
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zimonem ::
Xml je datoteka ti se pa sučeš v terminalskih vodah.
Tudi CLS ne boš posilil v xml.
Tudi CLS ne boš posilil v xml.
Zgodovina sprememb…
- spremenilo: Zimonem ()
MrStein ::
Nič se ne "sučem". Samo en java.lang.String pošiljam.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
kunigunda ::
Zakaj bi sam konvertiral?
Potem bo framework še enkrat "konvertiral" in bo na koncu rezultat:
<ns2:test1>1 + 1 = 3&#x000b2</ns2:test1>
(pišem kot navaden tekst, ker forum včasih zameša kodo)
Zgodovina sprememb…
- spremenilo: kunigunda ()
MrStein ::
Si pozabil napisat svoje besedilo?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
kunigunda ::
MrStein ::
Pričakujem, da klient, ki kliče to metodo, dobi točno to, kar je bilo poslano.
Torej:
Torej:
{ String rezultat = ws_client.test1(); char backspace = '\u0008'; String pričakovano = "1 + 1 = 3"+backspace+"2"; if(pričakovano.equals(rezultat)) System.out.println("pravilno"); else System.out.println("narobe!"); }
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
kunigunda ::
Pričakujem, da klient, ki kliče to metodo, dobi točno to, kar je bilo poslano.
Torej:
{
String rezultat = ws_client.test1();
char backspace = '\u0008';
String pričakovano = "1 + 1 = 3"+backspace+"2";
if(pričakovano.equals(rezultat))
System.out.println("pravilno");
else
System.out.println("narobe!");
}
To pa ni vec stvar jave ampak frameworka. Preveri oba (client in server), ali uporabljata UTF (Stringi po defaultu uporabljajo glede na OS razlicni encoding,
na linuxu je utf8, na windowsih cp1252). Sicer pa nastavi -D pri klicu jave (oz. IDE tud podpirajo, kaj je default)
WhiteAngel ::
Aja, še odgovor na vprašanje 1: Rezultat kode je invalid XML, ki ga bo vsak klient zavrnil z napako, ker znaki s kodo pod 0x20 so ilegalni v XML. (razen TAB, NL in CR, glej prejšnji link)
Saj si si že odgovoril. Ker XML ne podpira znakov pod 0x20, boš moral zgornji backspace (form feed, escape) escapati in jih potem spet pravilno dekodirati nazaj. Drugače ne gre.
kunigunda ::
Pa se, da bos lahko testiral, a ti bo marshaller pravilno naredu.
MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage soapMessage = messageFactory.createMessage(); SOAPPart soapPart = soapMessage.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); envelope.addNamespaceDeclaration("ws", "http://test"); SOAPBody soapBody = envelope.getBody(); SOAPElement e = soapBody.addChildElement("TestString", "ws"); e.addChildElement("Result", "1+1=3\u00082", "ws"); soapMessage.saveChanges(); soapMessage.getSOAPBody();
MrStein ::
To pa ni vec stvar jave ampak frameworka.
Seveda, saj to sem takoj na začetku napisal: Kaki drug framework (za Java), ki to pravilno hendla, je dobrodošel.
Pa se, da bos lahko testiral, a ti bo marshaller pravilno naredu.
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("ws", "http://test");
SOAPBody soapBody = envelope.getBody();
SOAPElement e = soapBody.addChildElement("TestString", "ws");
e.addChildElement("Result", "1+1=3\u00082", "ws");
soapMessage.saveChanges();
soapMessage.getSOAPBody();
In kaj tu ven pride? (zakaj si to napisal?)
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
kunigunda ::
To kodo sm dal cist tko da vids, kako interno stvar vrze exception zaradi backspaca. Verjetno pa vsak framework po svoje marshalizira soap xml.
MrStein ::
Vrže:
Kar sicer ni presenečenje. Oziroma nima preveč veze s primerom, ker gre tam za invalidne kode v textnode, tu pa si dal prefix.
Bolje on topic je:
Kar sploh ne vrže exception-a.
Exception in thread "main" org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.checkQName(CoreDocumentImpl.java:2582) at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:152) at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:80) at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.<init>(ElementImpl.java:97) at com.sun.xml.internal.messaging.saaj.soap.impl.ElementFactory.createElement(ElementFactory.java:78) at com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl.createElementNS(SOAPDocumentImpl.java:163) at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.createElement(ElementImpl.java:387) at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addChildElement(ElementImpl.java:302) at Dummy.soap(Dummy.java:141) at Dummy.main(Dummy.java:124)
Kar sicer ni presenečenje. Oziroma nima preveč veze s primerom, ker gre tam za invalidne kode v textnode, tu pa si dal prefix.
Bolje on topic je:
e.addTextNode("foobar3\u00082");
Kar sploh ne vrže exception-a.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
MrStein ::
Kar sicer ni presenečenje. Oziroma nima preveč veze s primerom, ker gre tam za invalidne kode v textnode, tu pa si dal prefix.
S tem, da v prefix-u niti '+' ali '=' ne sme biti, niti se ne sme začeti s števko, tako da je tisto res mimo teme (exception vrže zaradi števke na začetku, do BS sploh ne pride).
Za prenose stringov uporabi base64, če lahko?
Ja, vprašanje je, kako to narediti s čim manj sprememb v kodi (tako serverski kot klientski).
Izhodišče je lahko koda v prvem sporočilu.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
OracleDev ::
Spremembe so zgolj to, da na serverju zakodiraš in na klientu odkodiraš.
V web service dodaš nov import org.apache.commons.codec.binary.Base64; in nato return popraviš tako da zakodira. Je pa res da bi bilo pravilno da bi ti byte vračal servis (boš moral še v string pretvorit).
https://docs.oracle.com/javase/8/docs/a...
V web service dodaš nov import org.apache.commons.codec.binary.Base64; in nato return popraviš tako da zakodira. Je pa res da bi bilo pravilno da bi ti byte vračal servis (boš moral še v string pretvorit).
https://docs.oracle.com/javase/8/docs/a...
boolsheat ::
@OracleDev - malo si pomešal, če prav vidim - importal si Base64 class od Apache Commons knjižnjice, linkal pa do native jave class-a (ta je del jave od 1.8 dalje).
Nekaj takega:
Izpiše:
pravilno
Nekaj takega:
import java.io.UnsupportedEncodingException; public class Test { public static void main(String[] args) throws UnsupportedEncodingException { client(); } public static String test1() throws UnsupportedEncodingException { char backspace = '\u0008'; // backspace je locena spremenljivka le zato, da je lazje prebrati kodo return java.util.Base64.getEncoder().encodeToString(("1 + 1 = 3"+backspace+"2").getBytes()); } public static void client() throws UnsupportedEncodingException{ // String rezultat = ws_client.test1(); String rezultat = new String(java.util.Base64.getDecoder().decode(test1())); char backspace = '\u0008'; String pricakovano = "1 + 1 = 3"+backspace+"2"; if(pricakovano.equals(rezultat)) System.out.println("pravilno"); else System.out.println("narobe!"); } }
Izpiše:
pravilno
MrStein ::
Ja, načeloma to gre, ampak:
- potrebno spremeniti kodo na 57-ih mestih na serverju (in upati, da nisi kaj spregledal)
- potrebno je spremeniti vsakega klienta (zamisli si, da govorimo o kakem Google API-ju...)
- za bodoče kliente je treba nekje dokumentirati, da so xs:string podatki v resnici base64 kodirani stringi (v katerem encoding-u? Tvoj primer kode je nedefiniran glede tega!)
Dela, a daleč od elegantne (preproste) rešitve.
- potrebno spremeniti kodo na 57-ih mestih na serverju (in upati, da nisi kaj spregledal)
- potrebno je spremeniti vsakega klienta (zamisli si, da govorimo o kakem Google API-ju...)
- za bodoče kliente je treba nekje dokumentirati, da so xs:string podatki v resnici base64 kodirani stringi (v katerem encoding-u? Tvoj primer kode je nedefiniran glede tega!)
Dela, a daleč od elegantne (preproste) rešitve.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Zgodovina sprememb…
- spremenil: MrStein ()
MrStein ::
Plus, base64 je tu odveč. Pol lahko kar byte[] pošiljaš in prišparaš klic base64 na klientu in serverju.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
kunigunda ::
Ce hocs elegantne resitve da ti ne bo treba na 100 koncih popravljati, mas pa moznost svojega XML hendlerja dodati kjer bos sam predelal posebne znakce.
Je pa vprasanje, kako ta znak sploh pride kot response, oz. mogoce na kakem drugem mestu popravis (ne vem za kako arch. gre)
Aja uno kodo pa niti nism testiral, blo spisano v minuti, pa sm sam prvo vrstico gledu ne trejsa :) Sori.
Je pa vprasanje, kako ta znak sploh pride kot response, oz. mogoce na kakem drugem mestu popravis (ne vem za kako arch. gre)
Aja uno kodo pa niti nism testiral, blo spisano v minuti, pa sm sam prvo vrstico gledu ne trejsa :) Sori.
Zgodovina sprememb…
- spremenilo: kunigunda ()
boolsheat ::
Ja, načeloma to gre, ampak:
- potrebno spremeniti kodo na 57-ih mestih na serverju (in upati, da nisi kaj spregledal)
- potrebno je spremeniti vsakega klienta (zamisli si, da govorimo o kakem Google API-ju...)
- za bodoče kliente je treba nekje dokumentirati, da so xs:string podatki v resnici base64 kodirani stringi (v katerem encoding-u? Tvoj primer kode je nedefiniran glede tega!)
Dela, a daleč od elegantne (preproste) rešitve.
Se strinjam, da v tem primeru ni to elegantna rešitev... Ampak, IMO, karkoli boš naredil, bodo bolj ali manj potrebni vsi zgornji koraki, ker bi rad zaobšel standard... Pač slabo zamišljen API.
Drugače je mogoče tudi to opcija:
https://cxf.apache.org/docs/mtom.html
Zgodovina sprememb…
- spremenil: boolsheat ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Davčne blagajne (strani: 1 2 3 4 … 24 25 26 27 )Oddelek: Programiranje | 334898 (74901) | Macketina |
» | [Java] Prevajanje in šumniki v ubuntuOddelek: Programiranje | 2532 (2149) | mmaestro |
» | [Java]kompailiranje iz cmdOddelek: Programiranje | 1338 (1062) | ragezor |
» | [Java]Client/Server preko socketaOddelek: Programiranje | 1820 (1656) | KernelPanic |
» | Java - problem povezave na FTPOddelek: Programiranje | 1200 (1057) | igor0203 |