API request is looping using okHttp Client - java

I have the follow code that loops my script, I used debugger, and it goes to line return response.body().string(); then to catch (IOException e) without printing Exception, after that the Java app don't close. Any idea?
public static String getData(String httpLink) {
// Initialize an instance of OkHttpClient
OkHttpClient client = new OkHttpClient();
// Create a request object, with the URL containing the httpLink argument
Request request = new Request.Builder().url(httpLink).build();
// Try to execute the API call and retrieve a response
try (Response response = client.newCall(request).execute()) {
// If the response is successful and contains a body
if (response.isSuccessful() && response.body() != null) {
// Return the response body as a string
return response.body().string();
} else {
// Return null if the response is unsuccessful or contains no body
return "null";
}
} catch (IOException e) {
// Print the stack trace if an exception occurs
e.printStackTrace();
// Return null if an exception occurs
return "null";
}
}

Related

i write like this, but still got the error "A connection to XXX was leaked. Did you forget to close a response body? "

I don't know how to avoid it, i have closed the response body already!
Can someone help me solve this problem?
my code:
public String getPageFromServer(String activityKey) throws Exception {
String address = pageServerHolder.getServerAddressRandom();
String url = MessageFormat.format(URL, address, activityKey);
log.debug("=============== url [{}] ================", url);
OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS).callTimeout(1, TimeUnit.SECONDS).build();
final Request request = new Request.Builder().url(url).get().build();
Response response = client.newCall(request).execute();
try (ResponseBody body = response.body()) {
if (response.isSuccessful() && null != body) {
String bodyString = body.string();
if (StringUtils.isNotBlank(bodyString)) {
body.close();
return bodyString;
}
}
}
throw new RuntimeException(MessageFormat.format("获取活动页信息异常,url [{0}], response.code [{1}],response.message [{2}] ", url, response.code(), response.message()));
}
Your problem is that the Response is not closed. Your code should be something like this:
try (Response response = client.newCall(request).execute();
ResponseBody body = response.body()) {
if (response.isSuccessful() && null != body) {
String bodyString = body.string();
if (StringUtils.isNotBlank(bodyString)) {
return bodyString;
}
}
}
I'm not sure if you need to close the ResponseBody. It is possible that closing response will deal with it. However, there is little harm in a redundant close.
Check out the example here: https://square.github.io/okhttp/
ResponseBody implements the Closeable interface. You are creating ResponseBody in the resource section of the try block, it will be closed for you as you leave the try block.
Your "body.close()" should not be there.
try (Response response = httpClient.newCall(request).execute();
ResponseBody responseBody = response.body()) {
if (response.isSuccessful()) {
log.info("access tree from {} success", url);
return objectMapper.readValue(responseBody.string(), StorageTreeResponse.class);
} else {
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
I am wondering this is just a bug from okhttp client. Even the try resource syntax didn't solve the warnings.

How to verify response of any Http Request is valid JSON or not?

Suppose i have a Http request in json/xml when i post this request then we get some JSON response, then First i need to verify this response is valid json or not in java.how to do that in one go?
You can try to Deserialize, if it passes the Deserialize so it's a valid Json, if your Json is not valid it will return a Exception for you, try something like this:
//I'm using proxy with this request
RESTResponse response = await WebServiceProxy.GetInstance().Request(connection);
//Check if the response is a OK
if (response.statusCode == System.Net.HttpStatusCode.OK)
{
try
{
var obj = JsonConvert.DeserializeObject(response.content);
} catch(Exception ex) { }
}
A wild idea, try parsing it and catch the exception:
public boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}

Retrieve response body from ClientResource

I try to issue a POST request with ClientResource, I'm able to retrieve the response STATUS, I also want to get the response body when I get an exception.
Here is my code:
public static Pair<Status, JSONObject> post(String url, JSONObject body) {
ClientResource clientResource = new ClientResource(url);
try {
Representation response = clientResource.post(new JsonRepresentation(body), MediaType.APPLICATION_JSON);
String responseBody = response.getText();
Status responseStatus = clientResource.getStatus();
return new ImmutablePair<>(responseStatus, new JSONObject(responseBody));
} catch (ResourceException e) {
logger.error("failed to issue a POST request. responseStatus=" + clientResource.getStatus().toString(), e);
//TODO - how do I get here the body of the response???
} catch (IOException |JSONException e) {
throw e;
} finally {
clientResource.release();
}
}
Here is the code that my server resource returns in case of failure
getResponse().setStatus(Status.CLIENT_ERROR_FORBIDDEN);
JsonRepresentation response = new JsonRepresentation( (new JSONObject()).
put("result", "failed to execute") );
return response;
I try to catch the "result" with no success
In fact, the getResponseEntity method returns the content of the response. It corresponds to a representation. You can wrap it by a JsonRepresentation class if you expect some JSON content:
try {
(...)
} catch(ResourceException ex) {
Representation responseRepresentation
= clientResource.getResponseEntity();
JsonRepresentation jsonRepr
= new JsonRepresentation(responseRepresentation);
JSONObject errors = jsonRepr.getJsonObject();
}
You can notice that Restlet also supports annotated exceptions.
Otherwise I wrote a blog post about this subject: http://restlet.com/blog/2015/12/21/exception-handling-with-restlet-framework/. I think that it could help you.
Thierry

How to pass custom object in Post method of Restfull webservice

I have a requirement to recive some field value at webservice end which is passed by client in a custom object through Post call but its causes error like -
org.jboss.resteasy.client.ClientResponseFailure: Unable to find a MessageBodyReader of content-type text/html;charset="utf-8" and type null
at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:522)
at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:513)
at org.jboss.resteasy.client.core.BaseClientResponse.readFrom(BaseClientResponse.java:414)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:376)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:337)
at com.rest.jso.mainclient.RestJsonClient.processPOSTRequest(RestJsonClient.java:49)
at com.rest.jso.mainclient.RestJsonClient.main(RestJsonClient.java:33)
My webservice looks like -
#POST
#Path("/update/{user}")
#Produces("application/json")
public Response updateRecord(#PathParam("user")String user) {
User result = null;
//User result = new User();
try {
result = new ObjectMapper().readValue(user, User.class);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
result.setName("Ram");
return Response.status(200).entity(result).build();
}
My client to comsume the Rest service is -
public static void processPOSTRequest() /*throws ResponseStatusNotOKException*/{
User newUser = new User();
newUser.setName("My");
newUser.setId(22L);
newUser.setAddress("nagar");
ClientRequest clientRequest = new ClientRequest("http://localhost:8080/JsonRestExample/userService/update");
clientRequest.accept(MediaType.TEXT_HTML_TYPE);
ClientResponse<User> clientResponse = null;
try {
clientResponse = clientRequest.post(User.class);
if(clientResponse != null && clientResponse.getResponseStatus().getStatusCode() == 200) {
//User responseResult = clientResponse.getEntity();
String json = new ObjectMapper().writeValueAsString(clientResponse.getEntity());
System.out.println(json);
//System.out.println("updated address-> "+responseResult.getAddress()+"id=> "+responseResult.getId()+"Name=> "+responseResult.getName());
}else{
throw new ResponseStatusNotOKException("Response status is not OK.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
I'm searching for the root cause but still clue less .Any Idea how can I resolve this?
you can try post data by xml format, like this:
#POST
#Path("/update")
#Produces("application/xml")
public Response updateRecord(String requestXml) {
User result = null;
//User result = new User();
try {
result = fromXml(requestXml, User.class);
} catch (IOException e) {
e.printStackTrace();
}
result.setName("Ram");
return Response.status(200).entity(result).build();
}
while send http request,u need to convert User class to xml String,and then POST it.
The problem is that you don't define your request's body content.
In your client you should do :
clientRequest.body("application/json", input);
Where input is your newUser encoded in JSON. After this only you should call
clientResponse = clientRequest.post(User.class);

Why response from Jsoup.connect.execute is null? when throwing IOException?

My code look like this:
When I try to invoke this method with incorrect url e.g. http://en.dddddddddssss.org/ execute throw exception and response is null. Why? How can I got http code in that situation?
public Document getDocumentFromUrl(String url) throws SiteBusinessException {
Response response = null;
try {
response = Jsoup.connect(url).timeout(Constans.TIMEOUT).ignoreHttpErrors(false).userAgent(Constans.USER_AGENT)
.ignoreContentType(Constans.IGNORE_CONTENT_TYPE).execute();
return response.parse();
} catch (IOException ioe) {
LOGGER.warn("Cannot fetch site ]");
return null;
}
}
EDIT
public Document getDocumentFromUrl(String url) throws SiteBusinessException {
Response response = null;
try {
response = Jsoup.connect(url).timeout(Constans.TIMEOUT).ignoreHttpErrors(false)
.userAgent(Constans.USER_AGENT).ignoreContentType(Constans.IGNORE_CONTENT_TYPE).execute();
return response.parse();
} catch (HttpStatusException hse) {
LOGGER.warn("Cannot fetch site [url={}, statusMessage={}, statusCode={}]",
new Object[] { url, response != null ? response.statusMessage() : "<null>",
response != null ? String.valueOf(response.statusCode()) : "<null>" });
throw new SiteBusinessException(response != null ? response.statusMessage() : "<null>",
String.valueOf(response != null ? response.statusCode() : "<null>"));
} catch (IOException ioe) {
LOGGER.warn("IOException. Cannot fetch site [url={}, errorMessage={}]", url, ioe.getMessage());
throw new SiteBusinessException("Not found");
}
}
And then I'm trying to call http://localhost:8090/wrongaddress/. Jboss return HTTP 404.
But my code return
Cannot fetch site [url=http://localhost:8090/wrongaddress/, statusMessage=<null>, statusCode=<null>]
EDIT
WORKING SOLUTION
try {
response = Jsoup.connect(url).execute();
return processDocument(response.parse(), url);
} catch (IllegalArgumentException iae) {
LOGGER.warn("Malformed URL [url={}, message={}]", new Object[] { url, iae.getMessage() });
throw new SiteBusinessException(iae.getMessage());
} catch (MalformedURLException mue) {
LOGGER.warn("Malformed URL [url={}, message={}]", new Object[] { url, mue.getMessage() });
throw new SiteBusinessException(mue.getMessage());
} catch (HttpStatusException hse) {
LOGGER.warn("Cannot fetch site [url={}, statusMessage={}, statusCode={}]",
new Object[] { url, hse.getMessage(), hse.getStatusCode() });
throw new SiteBusinessException(hse.getMessage(), hse.getStatusCode());
} catch (IOException ioe) {
LOGGER.warn("IOException. Cannot fetch site [url={}, errorMessage={}]", url, ioe.getMessage());
throw new SiteBusinessException("Cannot fetch site");
}
No, it doesn't. You are catching the Exception and returning null by yourself. You can never throw an exception and return something at the same time.
There will be no HTTP code, since the host does not exist. HTTP codes are returned by the server. For example, the best known code is 404 (Not Found). When your browser shows 404, it is simply a HTTP/TCP packet send by the server to the client, that contains this code.

Categories

Resources