1 2 Previous Next 17 Replies Latest reply on Jul 18, 2013 11:33 AM by Los Morales

    url encoding in the address box for REST

    Los Morales Newbie

      Hi,

       

      I'm trying to access an external REST service using my resource composite service and in the bindings configuration for the properties in SY, in the Address textbox under the REST tab, it seems as though SY chokes on the address I give it, giving me a runtime exception of: 

      "Illegal character in query at index 75..." 

       

      I tried it straight out, encoded it, a few other things but I can't seem to get it to work.  The address looks like this:

       

      http://10.64.18.2/item_admin/services/CMS/Authentication/Authenticate?data={"LoginName":"administrator","Password":"testpassword"}

       

      Below is the screenshot I used:

       

      rest SY.png

       

       

      Any ideas?

        • 1. Re: url encoding in the address box for REST
          Keith Babo Master

          What happens when you encode the URL and what does your encoded URL look like?  You do have a mix of reserved and unsafe characters in that URL string.

          • 2. Re: url encoding in the address box for REST
            Magesh Bojan Master

            Have you tried this

            data%3D%7B%84LoginName%84:%84administrator%84,%84Password%84:%84testpassword%84%7D
            
            • 3. Re: url encoding in the address box for REST
              Los Morales Newbie

              I know it's not a clean REST uri since it mixes REST and JSON data but the original string works just fine when using any Web browser.

               

              Now I've already tried what Magesh suggested (encoding everything after ?) and I've encoded the entire uri-- same thing.  SY compiles and bootstraps on EAP just fine but then when I invoke this service, I get an invalid JSON back, something like this:

               

              {"Value":null,"Status":2,"Message":"Invalid username or password"}

               

              Looks like the string passed to the external REST service went ok, but I assume the external application couldn't decode (or doesn't decode) the encoded JSON data that was passed in hence the authentication failure.  I'm assuming the app needs to see the json data "normally" in order for it to work.

               

              Any other ideas?

              • 4. Re: url encoding in the address box for REST
                Magesh Bojan Master

                Looks like you have answered your question yourself once again .

                 

                The external application needs to accept encoded GET requests or else you can try if the application accepts POST/PUT.

                1 of 1 people found this helpful
                • 5. Re: url encoding in the address box for REST
                  Los Morales Newbie

                  It accepts post, so I reverted back to the original string.  For some reason, the jax-rs @PATH annotation automatically encodes the ? to %3F, but doesn't encode the =.  Hence I get the "Illegal character in path at index 77" error. 

                   

                  Here is what I put in my REST-based reference:

                   

                  @Path("/")

                  public interface InvokeExternalReference {

                   

                      // using the full uri fixed to test the REST service call.

                      @POST

                      @Path("Authentication/Authenticate?data={'LoginName':'administrator','Password':'testpassword'}")

                      @Produces({"application/xml","application/json"})

                            String authenticate(@PathParam("username") String username, @PathParam("password") String password);

                  }

                   

                   

                  This is what I put in the SY config:

                   

                      <sca:reference name="ExternalRestService" multiplicity="0..1" promote="InvokeExternalServiceBean/ExternalService">

                        <sca:interface.java interface="com.example.switchyard.switchyard_example.ExternalService"/>

                        <resteasy:binding.rest>

                          <resteasy:contextMapper/>

                          <resteasy:messageComposer class="com.example.switchyard.switchyard_example.CustomComposer"/>

                          <resteasy:interfaces>com.example.switchyard.switchyard_example.InvokeExternalReference</resteasy:interfaces>

                          <resteasy:address>http://10.64.18.2/item_admin/services/</resteasy:address>

                        </resteasy:binding.rest>

                      </sca:reference>

                   

                   

                   

                   

                  This is the error SY gives me:  Illegal character in path at index 77:http://10.64.18.2/item_admin/services/CMS/Authentication/Authenticate%3Fdata={'LoginName':'administrator','Password':'testpassword'}

                   

                  Notice it encoded the ? but nothing else...

                  • 6. Re: url encoding in the address box for REST
                    Los Morales Newbie

                    Not sure what is the correct way of configuring the REST uri in SY but I fiddled around a little bit and encountered a different error.

                     

                    What I did (and not sure if this is the right way) was to remove the address uri from the SY config (xml file) entirely and stick everything in the jaxrs-annotated reference service's PATH annotation.  It didn't complain about encoding any longer but now getting a 404 error:

                     

                    ERROR [org.switchyard.component.resteasy.OutboundHandler] (http-localhost/127.0.0.1:8080-1) Unexpected exception composing inbound Message from Outbound: org.jboss.resteasy.client.ClientResponseFailure: Error status 404 Not Found returned

                     

                     

                    My reference service now looks like this:

                     

                    @Path("/")

                    public interface InvokeExternalReference {

                     

                         // using the full uri fixed to test the REST service call.

                        @POST

                        @Path("http://10.64.18.2/item_admin/services/AMS/Authentication/Authenticate?data=%7B'LoginName':'administrator','Password':'testpassword'%7D")

                        @Produces({"application/xml","application/json"})

                              String authenticate(@PathParam("username") String username, @PathParam("password") String password);

                    }

                     

                     

                    And there is no <rest:address> element in the SY config any longer.

                     

                     

                    So would like to know what the proper way of doing this, as well as how to fix this issue I'm having with REST + JSON...

                     

                    TIA

                    • 7. Re: url encoding in the address box for REST
                      Magesh Bojan Master

                      You need to provide the address, unless it is running on localhost. After providing the address, encode the @Path value as done before. Have you tried this?

                      @Path("Authentication/Authenticate?data%3D%7B%84LoginName%84:%84administrator%84,%84Password%84:%84testpassword%84%7D")
                      
                      • 8. Re: url encoding in the address box for REST
                        Magesh Bojan Master

                        Besides, when I asked does the application accepts POST/PUT, is because you can send the JSON string in the body. Since the method seem to take only path parameters, why bother sending JSON? You can as well as send just the username and password can't you? One other thing is that your interface has path param different from the URL.

                        • 9. Re: url encoding in the address box for REST
                          Los Morales Newbie

                          Hi Magesh.

                           

                          Exactly what do you mean by "JSON string in the body"? 

                           

                          Out of this whole thing, all I want to do is invoke the external REST service using the following GET uri: 

                           

                          http://10.64.18.2/item_admin/services/CMS/Authentication/Authenticate?data={"LoginName":"administrator","Password":"testpassword"}

                           

                          From what I understand, I need to created this composite service that has a REST reference interface.  I would rather just implement the interface and invoke some REST client that would do what I'm asking but right now just trying to conform to SY best practice.

                           

                          As for the method I created, I don't really know if that is the right way.  The username and password will come in from the client, and I just want to populate the uri above with these two parameters.  Currently for testing, I fixed the uri to a known user/password hence the path parameters are not used.  If I can get this to work, then I'll stick back the dynamic parameters into the uri.

                           

                          To answer your other question about the encoded path, no that never worked.

                          • 10. Re: url encoding in the address box for REST
                            Los Morales Newbie

                            To give you a detail about the error using the encoded path you described, the external app chokes and returns the following error (decoded):

                             

                            http://localhost:8080/switchyard-example/authenticate/administrator/testpassword//item_admin/Error/index.htm?aspxerrorpath=/item_admin/services/CMS/Authentication/Authenticate?data={"LoginName":"administrator","Password":"testpassword"}

                            • 11. Re: url encoding in the address box for REST
                              Magesh Bojan Master

                              This particular piece of code seem to very client oriented

                              authenticate(@PathParam("username") String username, @PathParam("password") String password)
                              

                               

                              What I mean by JSON string is that the server side application could posisbly accept a JSON string simply like this shown below. In fact the interface there could be

                              authenticate(@PathParam("data") String jsonString)
                              

                               

                              or if it had been a POST method it could be

                              authenticate(String jsonString)
                              

                               

                              So in the case above for a POST method, you could just send the body as a JSON String. So, if for example, based on the rest-binding quickstart, if the above method is supposed to be invoked from a bean reference then it would be like this

                              @Inject @Reference
                              private Authenticator _authenticator;
                              
                              public authenticate() {
                                  authenticator.authenticate(myJSONString);
                              }
                              

                               

                              Where the Authenticator is just a Plain JAVA interface and not the REST interface. Now the reference binding would look like this

                              <reference name="Warehouse">
                                  <interface.java interface="org.switchyard.quickstarts.rest.binding.Authenticator"/>
                                  <rest:binding.rest xmlns:rest="urn:switchyard-component-resteasy:config:1.0">
                                  <rest:interfaces>org.switchyard.quickstarts.rest.binding.InvokeExternalReference</rest:interfaces>
                                  <rest:address>http://10.64.18.2/item_admin/services/AMS/Authentication/Authenticate</rest:address>
                                  </rest:binding.rest>
                              </reference>
                              

                               

                              Hope this helps!

                              • 12. Re: url encoding in the address box for REST
                                Los Morales Newbie

                                Hi Magesh.

                                 

                                Posts have been helpful but haven't been able to put it together. 

                                 

                                Say I do what you say.  I will still need to use a REST interface to invoke the external REST service right?  If so how will that look like?

                                • 13. Re: url encoding in the address box for REST
                                  Magesh Bojan Master

                                  The mapping from REST interface to the JAVA interface is done auto-agically. You need not do anything. I beleive you need to have a look at the quicstart that I have mentioned above and see how that works. There is a readme too there:

                                  https://github.com/jboss-switchyard/quickstarts/tree/master/rest-binding

                                   

                                  Let us know if you can't still figure it out.

                                  • 14. Re: url encoding in the address box for REST
                                    Magesh Bojan Master

                                    That is supposed to say auto-magically.

                                    1 2 Previous Next