Invoking a 'REST' service which have query parameters in the URL - java

I have to invoke a GET on a service which returns text/xml.
The endpoint is something like this:
http://service.com/rest.asp?param1=34&param2=88&param3=foo
When I hit this url directly on a browser (or some UI tool), all's good. I get a response.
Now, I am trying to use CXF WebClient to fetch the result using a piece of code like this:
String path = "rest.asp?param1=34&param2=88&param3=foo";
webClient.path(path)
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.TEXT_XML_TYPE)
.get(Response.class);
I was debugging the code and found that the request being sent was url encoded which appears something like this:
http://service.com/rest.asp%3Fparam1=34%26param2=88%26param3=foo
Now, the problem is the server doesn't seem to understand this request with encoded stuff. It throws a 404. Hitting this encoded url on the browser also results in a 404.
What should I do to be able to get a response successfully (or not let the WebClient encode the url)?

Specify the parameters using the query method:
String path = "rest.asp";
webClient.path(path)
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.TEXT_XML_TYPE)
.query("param1","34")
.query("param2","88")
.query("param3","foo")
.get(Response.class);

You will need to encode your URL. You can do it with the URLEncoder class as shown below:
Please replace your line
String path = "rest.asp?param1=34&param2=88&param3=foo";
with
String path = URLEncoder.encode("rest.asp?param1=34&param2=88&param3=foo");

Related

How to use + and ( or ) with url s query parameter using IntelliJ

I’m having a use case where I need to get response from server where the url looks like the below
https://urlname/path?query=test.project+IN+(integer value)+AND+test.folder+IN+(integer value).
This url returns json as response body n this is working with postman and browser.
But I’m getting status code 500 when I hit this from IntelliJ using io.restassured.response.Response class methods as below
Response res = given()
.auth()
.contentType(“json”)
.queryParam(query,param)
.get(url);
Try this code. This will access the url https://urlname/path?query=test.project+IN+(1234)+AND+test.folderId+IN+(5433)
String query = "query";
String params = "test.project+IN+(1234)+AND+test.folderId+IN+(5433)";
Response res = given().contentType(ContentType.JSON).auth().basic("", "").queryParam(query, params)
.urlEncodingEnabled(false).get("https://urlname/path");
Found the solution or rather I can found the actual problem that is I was writing the above code on Jira API’s and I was storing the username and password in a string variable which is used inside auth().basic(“”,””).
Since the password are encrypted it was not allowing RestAssured class to post or access the API.
So I used http clients Base64 password encoding and made the post call.

REST API is not responding while more characters given as query parameter

I am working on RESTEasy services to generate API for my application.
I tested with the below code to produce a simple string response,
#GET
#Path("/api")
public Response getUsers(#QueryParam("from") String from,) throws ProtocolException,
MalformedURLException, IOException {
return Response.status(200)
.entity("*************Hi Welcome*********************")
.build();
}
It is working fine with the following url
http://localhost:8080/myApp/f/api?from=any_string_here
But, this response available only while the query parameter value does not exceed 6246 characters.
If the query parameter value more than 6246 chars, there is no response available. Also, the browser network console shows the status code 400.
http://localhost:8080/myApp/f/api?from=more_than_6246_chars
I read that longer url needs to be send using POST, so I tried also with #POST method too for this, but browser network console shows the status code 405 and the following appears in eclipse console.
Apr 07, 2016 12:52:25 PM org.apache.tomcat.util.http.Cookies processCookieHeader
INFO: Cookies: Invalid cookie. Value not a token or quoted value
Note: further occurrences of Cookie errors will be logged at DEBUG level.
Is this longer URL is restricted by browser or RESTEasy application.
What would be the solution for this? Do I need to send more chars to my rest api parameter.
Webservers may reject requests if the URL exceeds a certain size.
Using a POST request alone does not help, you also need to decrease the URL size by putting URL parameters into the POST body.
You can try sending the parameters in request headers. I am using Jersey framework and angular JS in the front end. Sometimes I need to send a long JSON string for my application. I am sending it in the request headers and so far, I haven't got any issue like this.
My Rest Service class looks like below :
#Path("getStatus/agentName")
public class getStatus(){
#GET
public Response getStatus(#HeaderParam("header_name") String header_value){
String response = "Success" + header_value;
return Response.ok(response, MediaType.TEXT_PLAIN).build();
}
}
You can send your parameters in custom headers.
I think this should solve your problem.

URL Path Parameter Encoding

I'm struggling with path param encoding with retrofit:
http://localhost:8080/nuxeo/api/v1 is my base url.
I have this Call #GET("path/{documentPath}")
Call<Document> fetchDocumentByPath(#Path("documentPath") String docPath);
As param, I'm setting the following: default-domain/blabla
I run the query against my tomcat app and I get this answer
Response{protocol=http/1.1, code=400, message=Bad Request, url=http://localhost:8080/nuxeo/api/v1/path/default-domain%2Fblabla}
Even if I put encode = true to say "don't encode my parameter, it's already encoded", it's still encoding it.
Moreover, in retrofit, this test retrofit2.RequestBuilderTest#getWithEncodedPathParam doesn't work if we put Request request = buildRequest(Example.class, "po/ng"); with the following assertion: assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/po/ng/");
Tomcat has restricted his URL validation for security reason: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0450.
So I'd like to send '/' directly in my path parameter without encoding it in %2F. How can I achieve it?
Thank you!
Since parent-2.0.0-beta4, the parameter of the annotation of #Path is now working properly.

Parsing and encoding URL before sending to Rest webservice

I am developing an App where I am sending get request to REST web service using
#RequestMapping(value = "myURLpattern", method = RequestMethod.GET, produces = "image/png")
I came across a bug if somebody enters # in the URL query String it breaks from there
http://myserver.com:8080/csg?x=1&y=2#4&z=32&p=1
So I tried to encode it via filter HTTPRequestWrapper so that # will be replaced by %23 using URLEncoder.
My problem is for encoding URL, first I need to read the URL(request.getRequestURL()).
and getURL again can't read string after #.
request.getRequestURL() will return only (http://myserver.com:8080/csg?x=1&y=2)
Is there any other way to parse the complete url and encode it before sending to REST web service?
That is not a bug. Check this:
What is the meaning of # in URL and how can i use that?
A # in the url query string is wrong. You should encode it on client side, before sending it to your server. See this one: How to pass '#' in query string
It is in asp, but you should find the java equivalent.
Something to get you started can be this one Java URL encoding of query string parameters

How can I POST using Java and include parameters and a raw request body?

I am communicating with a web service that expects a POST parameter and also expect Request body. I have confirmed that such a POST request can be done using a REST Console I have, but I am unable to make such a request in Java using Apache libraries.
In the code below, I am able to POST to the web service, and it correctly receives the contents of the variable raw_body. If I uncomment the first of the two commented lines, the web service receives the "fname" parameter, but it no longer receives the body of the POST.
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
...
HttpClient httpClient = new HttpClient();
String urlStr = "http://localhost:8080/MyRestWebService/save";
PostMethod method = new PostMethod(urlStr);
String raw_body = "This is a very long string, much too long to be just another parameter";
RequestEntity re = new StringRequestEntity(raw_body, "text/xml", "UTF-16");
//method.addParameter("fname", "test.txt");
//httpClient.getParams().setParameter("fname", "test.txt");
method.setRequestEntity(re);
How can I transmit both the parameter and the body?
You could use the setQueryString method to add the parameters to the URL that is being POSTed to. From a RESTful perspective I'd argue you should normally not be doing that, however, since a POST should represent a call to a resource and anything that would qualify for a query parameter should be included in the representation that is being transferred in the request body...or it should represent qualification of the resource itself in which case it should be part of the path that is posted to which could then be extracted by the controller using #PathVariable/#PathParam or something similar. So in your case you could also be looking for something like POST /MyRestWebService/files/test.txt or more fittingly a PUT if you're saving the resource and know the URI. The code on the server could pull the filename out from a URL pattern.
You need to make a POST request using multipart-form. Here is the example:
Apache HttpClient making multipart form post
Alternatively, you can make a POST request with the content (parameters and files) encoded using application/x-www-form-urlencoded but it is not recommended when you want to make a POST request with large content, like files.

Categories

Resources