Issue when getting response from Apache HttpClient - httpclient

I'm trying to work with the response body of a HTTP POST action. I'm implementing the following method:
public class post2 {
public final static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
List<NameValuePair> formparams = new ArrayList <NameValuePair>();
formparams.add(new BasicNameValuePair("login_id", myID));
formparams.add(new BasicNameValuePair("api_key", myKey));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost(myURL);
httppost.setEntity(entity);
CloseableHttpResponse response2 = httpclient.execute(httppost);
try {
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
EntityUtils.consume(entity2);
String responseBody = EntityUtils.toString(entity2);
System.out.println("finalResult"+responseBody.toString());
}
finally {
httpclient.close();
}
}
}
I'm just receiving a "HTTP/1.1 200 OK", followed by:
Exception in thread "main" java.lang.ClassCastException: org.apache.http.impl.execchain.HttpResponseProxy cannot be cast to org.apache.http.HttpEntity
at post2.main(post2.java:62)
How should I recover the body information from the WebService?
Thanks,
Leo

Had to move EntityUtils.consume(entity2); to the end of the block:
public final static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
List<NameValuePair> formparams = new ArrayList <NameValuePair>();
formparams.add(new BasicNameValuePair("login_id", myID));
formparams.add(new BasicNameValuePair("api_key", myKey));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost(myURL);
httppost.setEntity(entity);
CloseableHttpResponse response2 = httpclient.execute(httppost);
try{
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
String responseBody = EntityUtils.toString(entity2);
System.out.println("finalResult"+responseBody.toString());
EntityUtils.consume(entity2);
}
finally {
httpclient.close();
}
}

Related

CloseableHttpClient: connection hangs forever

I have a problem with a connection managed by CloseableHttpClient.
A Spring service manages ny connection:
#Service
public class MyService {
...
private CloseableHttpClient closeableHttpClient;
public String setPayment() {
...
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader(ACCEPT, APP_JSON);
httpPost.setHeader(CONTENT_TYPE, APP_JSON);
StringEntity entity = new StringEntity(request, CHARSET);
httpPost.setEntity(entity);
CloseableHttpResponse response = closeableHttpClient.execute(httpPost);
logger.info("Execution");
} catch (IOException e) {
logger.error("Error");
}
}
}
My setPayment method is called max 3 times when execution is not successful. Sometimes after the first execution my method hangs with no response.
Any suggestion is welcomed.
I suggest you to do the following:
1) set timeout in a constructor:
public MyService() {
int timeout = 180;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(timeout * 1000)
.setConnectionRequestTimeout(timeout * 1000)
.setSocketTimeout(timeout * 1000).build();
closeableHttpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
}
2) use try-with-resources to manage CloseableHttpResponse
public String setPayment() {
...
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader(ACCEPT, APP_JSON);
httpPost.setHeader(CONTENT_TYPE, APP_JSON);
StringEntity entity = new StringEntity(request, CHARSET);
httpPost.setEntity(entity);
try (CloseableHttpResponse response = closeableHttpClient.execute(httpPost)){
logger.info("Execution");
} catch (IOException e) {
logger.error("Error");
}
}

Unable to access REST API’s in Camunda

In our project , we are trying to use camunda BPMN. using camunda standalone distro and deployed and running in Tomcat.
login as a admin user and able to access cockpit and task lists.But,when we try access the APIs using a Java client . we are getting an unauthorized (401) error. Though we are sending JSESSIONID as a “Cookie”
Tried both DefaultHttpClient and HttpURLConnection - It didn’t work out
Note : JSESSIONID is retrieved by calling the login api with admin username and password.
Help me to solve the issue
Attached below is the java client code
public static void main(String[] args) {
CamundaBMPNClient bpmnClient = new CamundaBMPNClient();
Map<Integer, String> cookieHeader = bpmnClient.getCookieHeader();
bpmnClient.getListofTasks(cookieHeader);
}
public Map<Integer, String> getCookieHeader() {
String jSessionID = null;
Map<Integer, String> headerValues = new HashMap<Integer, String>();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost request = new HttpPost(
"http://localhost:8090/camunda-webapp-tomcat-standalone-7.2.0/"
+ "api/admin/auth/user/default/login/cockpit");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.addHeader("Accept", "application/json");
String jsonString = new Gson()
.toJson("username=admin&password=admin#123");
StringEntity params;
try {
params = new StringEntity(jsonString);
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
Header[] cookieheader = response.getHeaders("Set-Cookie");
for (Header s : cookieheader) {
// Do your stuff here
System.out.println(s.getValue());
String[] str = s.getValue().split(";");
int i = 1;
for (String s1 : str) {
headerValues.put(i, s1.trim());
i++;
}
}
System.out.println("jSessionID::" + jSessionID);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return headerValues;
}
public void getListofTasks(Map<Integer, String> cookieHeader) {
int id = 0;
// DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost request = new HttpPost(
"http://localhost:8090/camunda-webapp-tomcat-standalone-7.2.0/api/engine/engine/default/task");
request.addHeader("Content-type", "application/json");
String[] arrJSessionID = cookieHeader.get(1).split("=");
System.out.println("" + arrJSessionID[1]);
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID=",
arrJSessionID[1]);
cookie.setDomain("http://localhost:8090");
cookie.setPath("/camunda-webapp-tomcat-standalone-7.2.0/");
// cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");
cookieStore.addCookie(cookie);
// httpclient.setCookieStore(cookieStore);
HttpClient httpclient = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore).build();
String jsonString = new Gson().toJson("{}");
StringEntity jsonStr;
try {
jsonStr = new StringEntity(jsonString);
request.setEntity(jsonStr);
HttpResponse response = httpclient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
Header[] header = response.getHeaders("Set-Cookie");
for (Header h : header) {
System.out.println(h.getValue());
}
System.out.println("statusCode::" + statusCode);
} catch (Exception e) {
e.printStackTrace();
}
}

Apache HttpClient - REST API: Issue in converting response to customized object which is put as SerializableEntity

I am using Apache HttpClient to put/get customized object using REST APIs. Below is the sample code. My putObject() method works fine and I could serialize Person object and put properly. However, while getting the object, I got below error:
Exception in thread "main" java.lang.ClassCastException: [B cannot be cast to Person at MyTest.demoGetRESTAPI(MyTest.java:88) at MyTest.main(MyTest.java:21)
Seems the code to build Person object out of response entity is not correct
HttpEntity httpEntity = response.getEntity();
byte[] resultByteArray = EntityUtils.toByteArray(httpEntity);
Person person = (Person)SerializationUtils.deserialize(resultByteArray);
Am I doing somthing wrong while getting byte[] array and converting to Person object. Please help me out to solve this issue.
Complete Example Program:
import java.io.Serializable;
import org.apache.commons.lang.SerializationUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.SerializableEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class MyTest {
public static void main(String[] args) throws Exception {
putObject();
getObject();
}
public static void putObject() throws Exception
{
HttpClient httpClient = new DefaultHttpClient();
Person person = new Person();
person.setName("Narendra");
person.setId("1");
try
{
//Define a postRequest request
HttpPut putRequest = new HttpPut("http://localhost:9084/ehcache-server/rest/screeningInstance/2221");
//Set the API media type in http content-type header
putRequest.addHeader("content-type", "application/x-java-serialized-object");
//Set the request put body
SerializableEntity personSEntity = new SerializableEntity(SerializationUtils.serialize(person));
putRequest.setEntity(personSEntity);
//Send the request; It will immediately return the response in HttpResponse object if any
HttpResponse response = httpClient.execute(putRequest);
//verify the valid error code first
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 201)
{
throw new RuntimeException("Failed with HTTP error code : " + statusCode);
}
}
finally
{
//Important: Close the connect
httpClient.getConnectionManager().shutdown();
}
}
public static void getObject() throws Exception
{
DefaultHttpClient httpClient = new DefaultHttpClient();
try
{
//Define a HttpGet request; You can choose between HttpPost, HttpDelete or HttpPut also.
//Choice depends on type of method you will be invoking.
HttpGet getRequest = new HttpGet("http://localhost:9084/ehcache-server/rest/screeningInstance/2221");
//Set the API media type in http accept header
getRequest.addHeader("accept", "application/x-java-serialized-object");
//Send the request; It will immediately return the response in HttpResponse object
HttpResponse response = httpClient.execute(getRequest);
//verify the valid error code first
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200)
{
throw new RuntimeException("Failed with HTTP error code : " + statusCode);
}
//Now pull back the response object
HttpEntity httpEntity = response.getEntity();
byte[] resultByteArray = EntityUtils.toByteArray(httpEntity);
Person person = (Person)SerializationUtils.deserialize(resultByteArray);
}
finally
{
//Important: Close the connect
httpClient.getConnectionManager().shutdown();
}
}
}
class Person implements Serializable{
String name;
String id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Override
public String toString() {
return "Person [name=" + name + ", id=" + id + "]";
}
}
I got the solution. It was mistake in my code:
While putting object, I have written below code. That was doing two time serialization. First from Person object to byte[] and second from byte[] to byte[].
SerializableEntity personSEntity = new SerializableEntity(SerializationUtils.serialize(person));
putRequest.setEntity(personSEntity);
This is the right approach:
SerializableEntity personSEntity = new SerializableEntity(person);
putRequest.setEntity(personSEntity);
After getting binary from REST, code should be like below to get Object:
HttpEntity httpEntity = response.getEntity();
InputStream inputStream = null;
try {
inputStream = httpEntity.getContent();
Person p = (Person) SerializationUtils.deserialize(inputStream);
System.out.println("Person:" + p.getName());
}
finally {
inputStream.close();
}
This worked like CHARM !!

Game port to unity: Web posting

I am porting a game from Java Native to Unity. While the game is working correctly, I am having trouble posting the score using the same web services.
Java Code:
public static String gameConfigURL = "http://192.168.0.140/services/scoreupload.svc/json/GetGameConfigurationLite";
public static String scoreUploadURL = "http://192.168.0.140/services/scoreupload.svc/json/Upload";
public static final String MagicKey = "0GmWDa6j";
private static int timeoutConnection = 60000;
public static enum RequestSource
{
Unknown,
System,
Person;
}
public static Response sendRequestForResult(Request request, String Url,
Activity activity, Response response) throws JSONException,
ClientProtocolException, IOException,ConnectTimeoutException {
/** Code to create a JSON request from requestObject **/
JSONObject object = request.getJSON();
JSONObject requestObject = new JSONObject();
requestObject.put("request", object);
Log.v("","REQUEST:"+requestObject.toString());
/** Add code to create a HttpPostRequest **/
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(Url);
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpResponse httpResponse = null;
String jsonValueString = null;
StringEntity se = null;
try {
se = new StringEntity(requestObject.toString());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-Type", "text/json");
/**
* add code to attach the JSON object received from request to the
* HttpPostRequest Add Code to execute HttpRequest
**/
httpResponse = client.execute(httpPost);
/** Get string from the HttpRespnse **/
jsonValueString = EntityUtils.toString(httpResponse.getEntity());
Log.v("","RESPONSE:"+jsonValueString);
/** Create JSON object from incoming String **/
JSONObject repliedObject = new JSONObject(jsonValueString);
response.fromJSON(repliedObject);
return response;
How Do I convert this to unity C#.
So far I have this:
JSONObject j = new JSONObject ();
j.AddField ("Id", "1234567890");
j.AddField ("MagicKey", ApplicationServices.magicKey);
j.AddField ("RequestedBy", "09996f84-1a06-e211-a518-001aa020d699");
j.AddField ("Timestamp", "/Date(1547535370953)/");
j.AddField ("RequestSource", "Person");
j.AddField ("RequestedGameId", "375b43c0-91be-e011-a505-001aa020d699");
j.AddField ("RequestedPersonId", "09996f84-1a06-e211-a518-001aa020d699");
string json = j.ToString ();
Dictionary<string, string> header = new Dictionary<string, string>();
header.Add ("Accept", "application/json");
header.Add ("Content-Type", "text/json");
byte[] encode = Encoding.ASCII.GetBytes (json.ToCharArray ());
WWW getConfig = new WWW (ApplicationServices.gameConfigURL, encode, header);
yield return getConfig;
if (getConfig.error != null) {
Debug.Log (getConfig.error);
} else {
Debug.Log (getConfig.text);
}
This does not seem to work.
For "POST" you should use WWWForm instead of WWW.
Take a look here

HTTP Status 500 - org.springframework.web.client.HttpClientErrorException: 404 /

I am using RestTemplate, but when i call postFor function i get following exception, Below are the code for showing detail:
Controller
#Controller
#RequestMapping("/data")
public class DataController {
#RequestMapping(value = "/{id}", method = RequestMethod.POST)
public ResponseEntity<ManagementResource> postData(#PathVariable("id") String id,#RequestBody Data1 data) {
RSResponse<Data1> response = new RSResponse<Data1>();
response.setStatus(RSResponse.Status.SUCCESS);
response.setData(data);
return new ResponseEntity<ManagementResource>(HttpStatus.CREATED);
}
}
client code:
RestTemplate rt = new RestTemplate();
Data1 d = new Data1();
d.setEmp_id(1);
d.setEmp_name("abc");
d.setEmp_salary(10000);
Map<String, String> vars = new HashMap<String, String>();
vars.put("id", "JS01");
String url = "http://localhost:8090/JSFFaceletsTutorial/data/{id}";
ResponseEntity<Data1> response = rt.postForEntity(url,d,Data1.class,vars);
Data1 data = response.getBody();
please tell if anyone knows it.
Thanks
Does your service need headers? If so, you can pass like this,
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Accept", "application/json");
HttpEntity<Data1> request = new HttpEntity<Data1>(d, headers);
ResponseEntity<Data1> response = rt.postForEntity(url,request,Data1.class,vars);
Data1 data = response.getBody();