I hava a java apache client written as :
public JSONObject createProject(String accessToken) throws PostEditException {
JSONObject jobj = new JSONObject();
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost("https://"+HOST_TRANSPORT+"/api/projects/create");
try{
post.addHeader("Content-Type","application/json");
post.addHeader("Accept","application/json");
String authorizationValue = "Bearer "+accessToken;
post.addHeader("Authorization",authorizationValue);
HttpResponse response = client.execute(post);
if (response == null) {
System.out.println("this is null");
}
int code = response.getStatusLine().getStatusCode();
if (code != 200) {
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = Charset.forName("UTF-8");
}
String errorBody = EntityUtils.toString(entity, charset);
log.info("createProject: Unable to process request. HTTP code: " + code + " responseBody: " + errorBody);
throw new PostEditException("createProject: Unable to process createProject request. HTTP code: " + code + " responseBody: " + errorBody);
} else {
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = Charset.forName("UTF-8");
}
String taggedResult = EntityUtils.toString(entity, charset);
jobj = new JSONObject(taggedResult) ;
}
}catch (NoRouteToHostException re) {
log.error("createProject: unable to route to host."+re);
throw new PostEditException("createProject: unable to route to host.",re);
}catch (IOException ie) {
log.error("createProject: problem executing HTTP request."+ ie);
throw new PostEditException("createProject: problem executing HTTP request.",ie);
}catch (Exception e) {
log.error("createProject: an error occurred." +e );
throw new PostEditException("createProject: an error occurred",e);
} finally {
post.releaseConnection();
}
return jobj;
} //createProject
so , I am trying to write a test case to mock the HttpClient.
so I Wrote the Mockito test case as :
PowerMockito.mockStatic(HttpClientBuilder.class);
HttpClientBuilder builderMock = Mockito.mock(HttpClientBuilder.class);
PowerMockito.doReturn(builderMock).when(HttpClientBuilder.class, "create");
HttpClient clientMock = Mockito.mock(CloseableHttpClient.class);
CloseableHttpResponse responseMock = Mockito.mock(CloseableHttpResponse.class);
Mockito.doReturn(clientMock).when(builderMock).build();
Mockito.doReturn(responseMock).when(clientMock).execute(Mockito.any());
classname obj= new classname();
Method m = classname.class.getDeclaredMethod("createProject", String.class);
JSONObject result =(JSONObject) m.invoke(obj,"accesstoken");
But when I debug the program, I see the real httpclient is created instead of the mocked one. How Do I create the mock httpclient so that I can mock the status and response as well.
Related
## sendPost method to make the POST call. It is fetching the url and also printing the data properly in the below method. ##
Public static void sendPost(String url, String data) throws Exception {
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
// add header
post.setHeader("User-Agent", "Mozilla/5.0");
StringEntity requestEntity = new StringEntity(data);
post.setEntity(requestEntity);
post.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.[`enter link description here`][1]append(line);
}
System.out.println(result.toString());
}
}
#RequestMapping(value="/test", method = RequestMethod.POST)
public #ResponseBody String sendTestData(#RequestBody TestDTO TestData) {
try{
log.info("Data got to ingestion rest: "+TestData);
String jsonData = new Gson().toJson(TestData).toString();
System.out.println("jsonData=="+ jsonData);
boolean result = dataIngestionHandler.insertData(jsonData);
if(result){
return "SUCCESS";
}
}catch(Exception ex) {
log.error("Error while inserting data into the db!!");
return "FAIL" + ex.getMessage();
}
return "FAIL";
}
I am sending the data from the sendPost method to the controller method, but in response it is giving:
405 exception
Exact error
code:{"timestamp":1467696109585,"status":405,"error":"Method Not
Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request
method 'POST' not supported","path":"/test"}.
The entire setup is running fine and data is getting inserted into the db when I run it on localhost. But as soon as I push it to cloud, the following exception comes up
Following is the code snippet in JAVA.
I want to do the similar thing in C#, Metro apps.
public static String callWebservice(String paramJson) throws Exception {
...
...
DefaultHttpClient httpclient = new DefaultHttpClient();
...
if (requestType.equals("POST") ) {
HttpPost httpPostReq = new HttpPost(url);
StringEntity se = new StringEntity(jsonParam.toString());
se.setContentType("application/json;charset=UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));
httpPostReq.setEntity(se);
httpresponse = httpclient.execute(httpPostReq);
}
else if (requestType.equals("GET") ) {
HttpGet httpGetReq = new HttpGet(url);
...
}
else if (requestType.equals("PUT") ) {
HttpPut httpPutReq = new HttpPut(url);
....
}
else if (requestType.equals("PATCH") ) {
HttpPatch httpPatchReq = new HttpPatch(url);
...
}
responseText = EntityUtils.toString(httpresponse.getEntity());
return responseText;
}
I wonder if there are separate methods of Java: ("HttpPost", "HttpGet", "HttpPut", "HttpPatch" ) in C# also.
I tried to accomplish the task using HttpClient but I'm facing errors while adding headers "Accept", "Content-Type", "X-Security-AuthKey" and throws error like:
Misued header ...
But somehow I managed to add header using "TryAddWithoutValidation".
In my C# code, I have the code snippet like following:
private async Task<string> CallHttpServiceHelper(string json)
{
try
{
...
HttpModel model = JsonConvert.DeserializeObject<HttpModel>(json);
try
{
JsonObject jsonObject = new JsonObject();
jsonObject["userName"] = JsonValue.CreateStringValue(model.paramss.userName);
jsonObject["password"] = JsonValue.CreateStringValue(model.paramss.password);
jsonObject["domain"] = JsonValue.CreateStringValue(model.paramss.domain);
jsonObject["accessKey"] = JsonValue.CreateStringValue(model.paramss.accessKey);
inputParams = jsonObject.Stringify();
}
catch (Exception ex)
{
}
url = model.url;
requestType = model.requesttype;
try
{
authenticationKey = model.authenticationKey;
}
catch (Exception ex)
{
}
if (requestType == "POST")
{
uri = new Uri(url);
data = new StringContent(inputParams, Encoding.UTF8, "application/json");
if (authenticationKey != null && authenticationKey != "")
{
data.Headers.Add("X-Security-AuthKey", authenticationKey);
}
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
httpClient.Timeout = TimeSpan.FromMinutes(10);
var response = await httpClient.PostAsync(uri, data);
content = await response.Content.ReadAsStringAsync();
httpClient.Dispose();
}
else if (requestType == "GET")
{
uri = new Uri(url);
httpClient = new HttpClient();
if (authenticationKey != null && authenticationKey != "")
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("X-Security-AuthKey", authenticationKey);
}
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
httpClient.Timeout = TimeSpan.FromMinutes(10);
var response = await httpClient.GetAsync(uri);
content = await response.Content.ReadAsStringAsync();
httpClient.Dispose();
}
else if (requestType == "PUT")
{
...
}
else if (requestType == "PATCH")
{
...
}
return content;
}
catch (Exception ex)
{
return "fail";
}
}
This code in C#, Windows RT Apps works fine for POST method. But I'm not getting the required response from webservice in GET method. In GET method I have to call WebService by passing three Headers only "Accept", "Content-Type", "X-Security-AuthKey".
I don't know what I'm doing wrong.
I've got org.apache.http.HttpResponse object, which I'm using at different places in the code. One of those places is for logging.
The problem is that when I run following log code:
HttpEntity entity = response.getEntity();
try {
String content = Base64.encodeToString(
EntityUtils.toByteArray(entity), Base64.DEFAULT);
sb.append(content + "\r\n");
} catch (Exception e) {
sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
+ "\r\n");
}
and than I try to read entry content in the actual processing code, that causes the code to throw following exception:
java.lang.IllegalStateException: Content has been consumed
My question is: how do I read the entity without consuming it in the log code?
UPDATE
here's the full code of the function I use to transform httpresponse to string:
static String toString(org.apache.http.HttpResponse response) {
try {
if (response == null) {
return "null";
}
StringBuilder sb = new StringBuilder();
sb.append("==============BEGIN HttpResponse================\r\n");
StatusLine sl = response.getStatusLine();
if (sl == null) {
sb.append("status line is null\r\n");
} else {
sb.append(String.format("%s %s\r\n", sl.getStatusCode(),
sl.getReasonPhrase()));
}
for (Header h : response.getAllHeaders()) {
if (h == null) {
sb.append("header is null\r\n");
continue;
}
sb.append(String.format("%s: %s\r\n", h.getName(), h.getValue()));
}
sb.append("\r\r\r\n");
HttpEntity entity = response.getEntity();
if (entity == null) {
sb.append("content is null");
} else {
try {
String content = Base64.encodeToString(
EntityUtils.toByteArray(entity), Base64.DEFAULT);
sb.append(content + "\r\n");
} catch (Exception e) {
sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
+ "\r\n");
}
}
sb.append("\r\n==============END HttpResponse================\r\n");
return sb.toString();
} catch (Exception e) {
return e.toString();
}
}
Ok. So what I ended up doing is implementing my own HttpEntity class, and than just using response.setEntity(...) to replace the previous entity. That class stores the result as binary array and returns it as many times as necessary.
It might give you some performance issues, but will work:
Example of my HttpClient with logging.
private CloseableHttpResponse invoke(HttpRequestBase http) {
try {
CloseableHttpResponse response = client.execute(http);
if (http instanceof HttpPost) {
InputStream inputStream = ((HttpPost) http).getEntity().getContent();
String body = IOUtils.toString(inputStream, Charset.defaultCharset());
HttpEntity respBody = response.getEntity();
String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
response.setEntity(new StringEntity(responseBody));
LOG.info(String.format("Sending request: [%s] %s => [%s] \nPayload:\n%s \nResponse:\n%s", http.getMethod(), http.getURI(), response.getStatusLine(), body, responseBody));
} else {
LOG.info(String.format("Sending request: [%s] %s => [%s]", http.getMethod(), http.getURI(), response.getStatusLine()));
}
return response;
} catch (IOException e) {
throw new RuntimeException("HTTP request failed: " + http.toString(), e);
}
}
Main idea is following:
1. make http call
2. copy to string your response body:
HttpEntity respBody = response.getEntity();
String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
log it
set new response entity like response.setEntity(new StringEntity(responseBody));
This example work good for small test framework, not sure it's good code for production application
I want to write put Curl to java:
curl -X PUT -u username:password http://localhost:80/api/client/include/clientID
Thats what I googled but my problem is that how can I pass the value of client_id and client to put since there is an /include between them. I am a bit confused of how to write a curl. Can any one help me?
public String RestPutClient(String url, int newValue, int newValue2) {
// example url : http://localhost:80/api/
DefaultHttpClient httpClient = new DefaultHttpClient();
StringBuilder result = new StringBuilder();
try {
HttpPut putRequest = new HttpPut(url);
putRequest.addHeader("Content-Type", "application/json");
putRequest.addHeader("Accept", "application/json");
JSONObject keyArg = new JSONObject();
keyArg.put("value1", newValue);
keyArg.put("value2", newValue2);
StringEntity input;
try {
input = new StringEntity(keyArg.toString());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return success;
}
putRequest.setEntity(input);
HttpResponse response = httpClient.execute(putRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
result.append(output);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
I assume the parameters you are passing are supposed to represent client and clientID. You simply need to build the URL your passing to HttpPut from your parameters.
If these are your parameters
url = "http://localhost:80/api/";
newValue = "client";
newValue2 = "clientID";
then your HttpPut initialization would look like this
HttpPut putRequest = new HttpPut(url + newValue + "/include/" + newValue2);
Also see:
How do I concatenate two strings in Java?
I'm having this issue and I need to put or patch data to the server. I know how to do a standard post, but how can I do this PATCH or PUT to the server?
The URL to the server is PATCH to www.example.com/api/documents and parameter is doc_id(integer).
This is what I currently have
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("content-type", "application/json");
httpPost.setHeader("accept-charset", "utf8");
try {
HttpResponse response = httpClient.execute(httpPost);
responseString = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
Log.e("Request exception:", "excpetion", e);
}
return responseString;
But this code I think is wrong as hell :)
This is the most common way---
Creating jsonObj and putting json values:
JSONObject jsonObj = new JSONObject();
jsonObj .put("doc_id", <put your value> + "");
String response = callPutService(source, password, callingAPI, jsonObj);
This is the callPutService that is called:
public String callPutService(String userName, String password,
String type, JSONObject jsonObject) {
String line = null, jsonString = "";
HttpResponse response = null;
InputStream inputStream = null;
try {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.
setConnectionTimeout
(client.getParams(), 20000); // Timeout Limit
HttpPut put = new HttpPut(WEBSERVICE + type);
StringEntity se = new StringEntity(jsonObject.toString());
se.setContentType("application/json;charset=UTF-8");
put.setHeader("Authorization",
"basic " + Base64.
encodeToString((userName + ":" + password).getBytes(),
Base64.URL_SAFE | Base64.NO_WRAP));
put.setEntity(se);
response = client.execute(put);
int responseCode = response.getStatusLine().getStatusCode();
if(responseCode == 200){
//do whatever
}
} catch (Exception e) {
e.printStackTrace();
}
return jsonString;
}