Retrieve response body from ClientResource - java

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

Related

WP Rest API - Post to ACF field?

I'm trying to post to my custom Wordpress field via the REST API from my android app. That said, when I look at the JSON structure of any ACF fields, they're nested inside "acf" like so:
{
"acf": {
"phone_number": "000-0000"
}
}
I'm trying to post a phone number to the phone_number field at my endpoint with the following code/structure, but it won't seem to save?
OkHttpClient client = new OkHttpClient();
String url = "http://myurl.com/wp-json/wp/v2/users/loggedinuser/36";
String bearer = "Bearer ";
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("phone_number", "777-348-4349");
} catch (JSONException e) {
e.printStackTrace();
}
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url(mergeUrl)
.method("POST", body)
.addHeader("Accept-Charset", "application/json")
.addHeader("Authorization", bearer + userToken)
.addHeader("Content-Type", "application/json")
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String resStr = response.body().string();
int responseCode = response.code();
if (responseCode == 200) {
} else {
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return null;
}}
I imagine it's because phone_number is nested inside of "acf". How can I write this line:
jsonObject.put("phone_number", "777-348-4349");
so that it matches the structure above? I can't seem to figure out how to nest phone_number inside of the acf value.
Here's how you can nest it to match the structure:
JSONObject jsonObject = new JSONObject();
try {
JSONObject acf = new JSONObject();
acf.put("phone_number", "777-348-4349");
jsonObject.put("acf", acf);
} catch (JSONException e) {
e.printStackTrace();
}
let me know if this worked for you.
Using ACF with the REST API is explained on this page. To sum it up:
You need at least ACF version 5.11
You need to enable the REST API for your field groups
The endpoints for users are /users/{user_id} and /users/me (not /users/loggedinuser/{user_id})
The JSON structure is the following:
{
"acf":
{
"field": "Value"
}
}

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;
}

empty POST body to JSON using ObjectMapper

i'm trying to read the POST payload using object mapper
ServletInputStream in = null;
try {
in = request.getInputStream();
originalInputStreamMap = mapper.readValue(in,
new TypeReference<Map<String, String>>() {
});
somemap.putAll(somattr);
} catch (RuntimeException ex) {
ex.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
but if the POST request body is empty
mapper.readValue
will throw an error. my use case is that if there is no request body, i need to set the hashmap to the request body(somemap).

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);

Categories

Resources