Can't get JSON from a GET request - java

New to Play! Framework and web development in general, I'm trying to do a simple REST GET to a web service and just get some straight-forward JSON in response. Typing the URL into a browser, I get a perfect response, with nicely formatted JSON. Calling it via code, it just blows up:
WS.WSRequest wsRequest = WS.url( serviceURL );
wsRequest.timeout( timeoutTime );
wsRequest.setHeader("Accept", "application/json");
wsRequest.headers.put( "Content-type","application/json" );
wsRequest.mimeType = "application/json";
WS.HttpResponse response = wsRequest.get();
String graphServiceResponse = response.getJson().toString();
Everything executes fine, until the last line where it throws an exception and errors out. I know I have what looks like a lot of redundant code; those are my attempts to fix it. Like I said, typing the "serviceURL" into a browser, it works fine.
Anyone know what I'm doing wrong? Thanks in advance!

Okay, solved this. Just omitted all the sets and such, added authentication and it worked perfectly. Weird.
String stringResponse = "";
try {
// execute GET to graph service
WS.WSRequest wsRequest = WS.url( serviceURL ).authenticate( USERNAME, PASSWORD );
WS.HttpResponse response = wsRequest.get();
stringResponse = response.getString();
... more cool stuff ...
Thanks for looking!

I have tried and found this below code working. 10000 is the timeout parameter in ms.
String baseUrl = "your url";
F.Promise<WSResponse> response = ws.url(baseUrl)
.setQueryParameter(param, value)
.get();
return response.get(10000).asJson().toString();

Related

How to send Entity in API DELETE with HTTP-CLIENT

I have to call a DELETE Method inside one of the APIS of a client.
This shouldn´t be a problem but I am struggling with the framework that my company currently uses and I hope I can get some info that hopefully will help me solve the problem:
First thing first.
1: The api doesn´t work if I do the call sending the params as URL:
2: It works completely OK if I send the params inside the body as x-www-form-urlencoded but not form-data or raw
The documentation of the method inside the API told us the following: (Important to Look to IDEtapa)
I have to do this call in JAVA (JAVA 8)
currently my company uses HTTP_CLIENT as the main framework for APICalls.
My code:
The build of the Data (Currently I build both, as Entity and as Params for you to view I´ve tried with each one of them indepently):
Map datosApi = new HashMap<>();
datosApi.put(Constants.URL, anular_cita);
Map headers = new HashMap<>();
headers.put(Constants.AUTHORIZATION, params.get("token_autorizacion"));
headers.put("Content-Type", "application/json");
headers.put("entity_charset", "UTF-8");
datosApi.put(Constants.HEADERS, headers);
JSONObject entity = new JSONObject();
Map param = new HashMap();
param.put(Constants.ID_CENTRO, consul);
param.put("IdAsistencia", propiedades[0]);
param.put("IdCapitulo", propiedades[1]);
param.put("IdEtapa", Integer.valueOf(propiedades[2]));
entity.put(Constants.ID_CENTRO, consul);
entity.put("IdAsistencia", propiedades[0]);
entity.put("IdCapitulo", propiedades[1]);
entity.put("IdEtapa", Integer.valueOf(propiedades[2]));
datosApi.put("entity", entity.toString());
datosApi.put("entity_mime_type", "application/json");
datosApi.put("entity_charset", "UTF-8");
datosApi.put("params", param);
String anularCita = APIDao.callAPIDelete(datosApi);
The preparation for my call to the framework:
public static String callAPIDelete(Map in) {
String contentString = "";
Map res = new HashMap<>();
try {
res = XWM.execute("delete#http_client", in);
byte[] content = (byte[]) res.get("content");
contentString = new String(content, StandardCharsets.UTF_8);
And inside our framework we have this:
if (StringUtils.equals(StringUtils.trim(method), "delete"))
{
StringBuilder requestUrl = new StringBuilder(url);
if (formparams != null)
{
if (requestUrl.indexOf("?")==-1) requestUrl.append("?");
else requestUrl.append("&");
requestUrl.append(URLEncodedUtils.format(formparams, charset));
}
if (entityRequest != null)
{
log.error("Param 'entity' no puede usarse en get (se ignora)");
}
HttpDelete delete = new HttpDelete(requestUrl.toString());
delete.setConfig(requestConfig);
uriRequest = delete;
}
}
}
}
// Headers
if (headers != null)
{
for (String h: headers.keySet()) uriRequest.addHeader(h, headers.get(h));
}
// Ejecutamos método
log.info("Executing request " + uriRequest.getRequestLine());
CloseableHttpResponse response = null;
if (!preemtiveAuth || credsProvider == null)
{
response = httpclient.execute(uriRequest);
}
As you can see, in the delete method, we ignore the entity that i´ve built in the first patch of code.
The HTTPDelete Class is APACHE, the url with info of the class is the following:
https://www.javadoc.io/doc/org.apache.httpcomponents/httpclient/4.5.2/org/apache/http/client/methods/HttpDelete.html
The question can be divided in two:
1: Can we send the Entity in a Delete Call? I have found a few info about this in the following places:
Is an entity body allowed for an HTTP DELETE request?
https://web.archive.org/web/20090213142728/http://msdn.microsoft.com:80/en-us/library/cc716657.aspx
https://peterdaugaardrasmussen.com/2020/11/14/rest-should-you-use-a-body-for-your-http-delete-requests/
I assume that in order to do it, i would need a new HttpDelete that would allow us to use entity, if possible, could you give me some examples of this?
2: For what i understand of the links i posted above, while using entity in Delete calls is not forbidden is something that is not encouraged, Should I just talk with the people who made the API and ask them to change their configuration to allow us to send the info by params? (It is not personal or sensible info, just a bunch of IDs)
Thank you so much for your attention and my apologies for any typo or format mistake, still learning how to make good posts.
EDIT: i have found this answer setEntity in HttpDelete that more or less solve the first issue about if its, posible to send an Entity in a Delete call, but still, don´t now if it should be better to ask them to change their method
As told in the coments by Ewramner and VoiceOfUnreason and in the edits:
1: The answer about how to make this was found in an older post of StackOverflow: setEntity in HttpDelete
2: The answer about "Should I just talk with the people who made the API and ask them to change their configuration to allow us to send the info by params?" was answered by both of them. While it´s not forbidden, it´s something thats not recommended.
My course of action will be:
1: Talk with the people responsible for the API to give them info about this situation.
2: Ask our Architecture team to create a new method that will allow us to do HttpDelete calls with an entity body, just in case that we have to make more API calls like this one.
With this i think all my answers are solved.
Again, Thank you.

swift 3 webservice multiple time data inserted in DB using REST API

I am hitting the REST API server as a client using Swift 3 programming, I have sent request once and a single response. But the problem is once i posted my data's the data's are inserted twice and getting the response based on the second insert value.
For Example: When i posted new mail address, it inserted into Database, and it iterated again and trying to insert again and i get the response as "Email is already registered". I have tried all the methods from my client side programming.
Few have said that the server by itself restarted again after 40 sec, i'm not sure if that is the case how to overcome this problem.
CODE IN SWIFT 3 CLIENT:(iOS)
func getMailAddress(mailID: String) {
let username = "admin"
let password = "admin"
let loginString = String(format: "%#:%#", username, password)
let loginData: NSData = loginString.data(using: String.Encoding.utf8)! as NSData
let base64LoginString = loginData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
let getUrl = URL(string: "http://localhost/rest/merchantsignup/mailExists/\(mailID)")
var request = URLRequest(url: getUrl!)
request.httpMethod = "GET"
request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")
let urlConnection = NSURLConnection(request: request, delegate: self)
urlConnection?.start()
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
} else {
do {
let myJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
print("myJSON:\(myJSON)")
} catch let err as NSError {
print(err)
}
}
}
task.resume()
}
CODE IN JAVA REST WEBSERVICES:
#GET
#Path("/mailExists/{emailId}")
#Produces(MediaType.APPLICATION_JSON)
public RestResMessagesVO mailExists(#PathParam("emailId")String emailId){
System.out.println(emailId);
MerchantRegistrationDAO mcdao = new MerchantRegistrationDAO();
RestResMessagesVO resObj = new RestResMessagesVO();
resObj.setMessage(mcdao.ismcEmailorPhoneExists("emailAddress",emailId.trim()));
return resObj;
}
You are trying to establish a connection with basic authentication, but actual problem here, while your requesting your server it get hitted twice is
1. you established your connection using request so, by that time it hitted the server once.
2. Then you created an object for NSURLConnection, and you started the connection, by that it hits the server second time.
Because of this only you hit your server twice, and get the response based on the second server hit.
Solution: Try this to overcome your Problem:
let username = "admin"
let password = "admin"
let loginString = String(format: "%#:%#", username, password)
let loginData: NSData = loginString.data(using: String.Encoding.utf8)! as NSData
let base64LoginString = loginData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
let getUrl = URL(string: "Your URL String")
var request = URLRequest(url: getUrl!)
request.httpMethod = "GET"
request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request)
{ (data, response, error) in
if error != nil
{
print(error!)
}
else
{
do {
let JSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print("YOUR RESPONSE: \(JSON)")
}
catch let err as NSError
{
print(err)
}
}
}
task.resume()
probably that's because you are calling
urlConnection?.start()
and
task.resume()

fill a form in a asp dynamic page with htmlunit

I'm making a little script in java to check iPhone IMEI numbers.
There is this site from Apple :
https://appleonlinefra.mpxltd.co.uk/search.aspx
You have to enter an IMEI number. If this number is OK, it drives you to this page :
https://appleonlinefra.mpxltd.co.uk/Inspection.aspx
Else, you stay on /search.aspx page
I want to open the search page, enter an IMEI, submit, and check if the URL has changed. In my code there is a working IMEI number.
Here is my java code :
HtmlPage page = webClient.getPage("https://appleonlinefra.mpxltd.co.uk/search.aspx");
HtmlTextInput imei_input = (HtmlTextInput)page.getElementById("ctl00_ContentPlaceHolder1_txtIMEIVal");
imei_input.setValueAttribute("012534008614194");
//HtmlAnchor check_imei = page.getAnchorByText("Rechercher");
//Tried with both ways of getting the anchor, none works
HtmlAnchor anchor1 = (HtmlAnchor)page.getElementById("ctl00_ContentPlaceHolder1_imeiValidate");
page = anchor1.click();
System.out.println(page.getUrl());
I can't find out where it comes from, since i often use HTMLUnit for this and i never had this issue. Maybe because of the little loading time after submiting ?
Thank you in advance
You can do this by using a connection wrapper that HTMLUnit provides
Here is an example
new WebConnectionWrapper(webClient) {
public WebResponse getResponse(WebRequest request) throws IOException {
WebResponse response = super.getResponse(request);
if (request.getUrl().toExternalForm().contains("Inspection.aspx")) {
String content = response.getContentAsString("UTF-8");
WebResponseData data = new WebResponseData(content.getBytes("UTF-8"), response.getStatusCode(),
response.getStatusMessage(), response.getResponseHeaders());
response = new WebResponse(data, request, response.getLoadTime());
}
return response;
}
};
With the connection wrapper above, you can check for any request and response that is passing through HTMLUnit

Java : How to handle POST request without form?

I'm sending a http post request from javascript, with some json data.
Javascript
var data = {text : "I neeed to store this string in database"}
var xhr= new XMLHttpRequest();
xhr.open("POST","http://localhost:9000/postJson" , true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(data);
xhr.setRequestHeader("Connection", "close");
//Also, I've tried a jquery POST
//$.post('postJson', {'data=' : JSON.stringify(data)});
//But this doesn't make a request at all. What am I messing up here?
Route
POST /postJson controllers.Application.postJson()
Controller
public static Result postJson(){
//What should I write here to get the data
//I've tried the below but values is showing null
RequestBody rb=request().body();
final Map<String,String[]> values=rb.asFormUrlEncoded();
}
What is the way to parse the POST request body?
Much thanks!
Retreive the request body directly as JSON... no need to complicate your life.
public static Result postJson() {
JsonNode rb = request().body().asJson();
//manipulate the result
String textForDBInsertion = rb.get("text").asText(); //retreives the value for the text key as String
Logger.debug("text for insertion: " + textForDBInsertion
+ "JSON from request: " + rb);
return ok(rb);
}
Also, I recommend you use the AdvancedRestClient Chrome plugin for testing. This way you can eliminate from the equation client-side code errors.
Cheers!

How to get SoapUI request and response XML in java

I'm using the SoapUI API as part of an existing java project.
The application should save the request and response XML in an specific report file.
I wonder if it's possible to get those requests and responses via the API.
The method invoking the TestCaseRunner looks like this
protected void checkTestCase(TestCase testCase) {
TestCaseRunner tr = testCase.run(null, false);
for (TestStepResult tcr : tr.getResults()) {
String status = tcr.getStatus();
String time = tcr.getTimeTaken() + "ms";
/* How to get XML messages?
* String request =
* String response =
*/
}
}
Depending on exactly what kind of test steps you have they might be an instance of a MessageExchange. Casting the TestStepResult to a MessageExchange and calling getRequestContent / getResponseContent might do the trick.
String request = ((MessageExchange)tcr).getRequestContent();
String response = ((MessageExchange)tcr).getResponseContent();
I have used the following way to get the response from the API CAll performed:
runner = testRunner.runTestStepByName("Your Test Case name");
// Here we take the response in ms of the API call
timeTaken = runner.response.timeTaken;
// here we get the HTTP response code.
responseCode = runner.getResponseHeaders()."#status#";
// here we get the response content
String response = runner.getResponseContent();
// here we get the API call endpoint -> in case you need to print it out.
String endPoint = runner.getEndpoint();

Categories