Ich habe einen JAX-RS REST Service auf einem Tomcat laufen. Persistiert wird mittels JPA auf einer HSQL Datenbank. Läuft alles soweit prima, bis ich eine URL an meinen Service schicken will.
z.B angenommen ich hab einen Service auf dem Pfad “/link/{link}”. Auf dieses Service will ich jetzt die url “http://www.google.com” schicken.
Mittels Javascript kann ich schon beim ajax Aufruf auf mein Service durch encodeURIComponent() mal umwandeln in “http%3A%2F%2Fwww.google.com”.
Dann hab ich noch gefunden, dass der Tomcat die encodeten Slashes per default nicht akzeptiert und man ein SystemProperty setzen muss. Also hab ich meinem web-xml noch folgendes eingefügt:
[XML]
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH
true
[/XML]
Geholfen hat das aber alles nix, es fliegen Servlet errors. Was mache ich falsch?
Servlets + Datenbank im Titel, Javascript/ Ajax im Text,
bisschen viel auf einmal, es doch nur um ‘vom Client zum Webserver als Paramter übertragen’, das hat mit Datenbank zumindest nichts zu tun?
funktioniert nebenbei interessant ein ganz normales Formular mit Senden-Button?
kann ich selber nicht testen, aber sollte doch in der Welt bisher aufgefallen sein wenn Slash da nicht zu übertragen ist,
wie sieht es bei dir aus?
falls es normal geht, bist du aber auf Ajax und ähnlich komisches angewiesen?
wie steht es um naheliegende Workarounde, je nachdem wieviel du auf beiden Seiten kontrollierst:
nur ‘www.gurke.com’ senden, den Anfang dazu kann man sich im einfachen Fall denken, falls überhaupt nötig
eigene individudelle Encode-Routine (keine Ahnung ob mit JavaScript gut möglich), die “http:SLASHSLASHwww.gurke.com” oder ähnliches sendet,
wenn nötig mit den üblichen Sicherungen: tatsächlich normale Vorkommen SLASH in SSLASH umwandeln bzw. alle S in SS wohl nötig, na wie man das so macht
Ist der AJAX-Request ein POST oder ein GET? Bei POST müsste nichts encodet werden. Bei GET evtl. Aber da wäre anzumerken, ob ein Umstieg auf POST möglich wäre. Denn Du willst hier Daten auf dem Server speichern (create oder update). Da ist in der REST-Welt von der Semantik her POST zu verwenden.
bisschen viel auf einmal, es doch nur um ‚vom Client zum Webserver als Paramter übertragen‘, das hat mit Datenbank zumindest nichts zu tun?
Das denke ich mir ja auch. www.google.com funktioniert, die „/“ wollen nicht. Ohne encoding fliegt ein not found error - „http://myservice.com/link/http://www.google.com“ ist natürlich keine gültige ressource… Der übliche Workaround ist eben mittels encodeURIComponent - das sieht man ja auch öfters in der Adressleiste bei Weiterleitungen.
Ja, der Ajax request ist ein POST. Wie gesagt, ohne encoding not Found, mit Encoding folgendes:
Schwerwiegend: Servlet.service() for servlet [Jersey REST Service] in context with path [/Listen2Me] threw exception [javax.persistence.RollbackException: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: Track [trackId=0, artist=null, title=null, album=null, genre=null, link=null].] with root cause
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: Track [trackId=0, artist=null, title=null, album=null, genre=null, link=null].
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:310)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:723)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1516)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
at jku.se.listen2me.services.Views.tracks(Views.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:406)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:350)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:106)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:219)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)```
Die Exception sagt mir jetzt eher wenig, ich weis jedoch, dass der Service beim Call mit der enkodierten URL gar nicht ausgeführt wird.
PS: gibts eigentlich einen Code-Tag für Error/Stacktraces?
*** Edit ***
Ok ich geb mal Entwarnung erster Stufe, anscheinend habe ich das Systemproperty falsch gesetzt. Hab mich darauf verlassen einen "no slash" error zu bekommen - dem war nicht so. Anscheinend bekomm ichs noch hin, ansonsten meld ich mich :)
*** Edit ***
Vielen Dank nochmal für die Hilfe, ich habs hinbekommen. Oft hilft es schon wenn man das ganze einfach mal Aufschreibt anstatt ewig darüber zu brüten :D
Es lag an diesem SystemProperty. Tomcat hat so einen “bugfix” gegen ein Sicherheitsproblem in Bezug auf enkodierte Slashes, also auf “%2F”. Ich dachte ich kann das Property in der Web-xml setzen, dem war nicht so. Ich hatte im Internet gelesen, dass Tomcat eine “no Slash Exception” oder so ähnlich werfen würde, was er nicht gemacht hat.
Gibts für Eclipse eigentlich auch eine schöne GUI mit der man einen Server konfigurieren kann? Die Server Properties sind bei mir extrem mager (“General” und “Monitoring”) und ich hab das Property jetzt in der RunConfiguration gesetzt.