HttpURLConnection very slow - java

Can anyone spot why this takes ~20 sec?
I am running the code below to post a JSON request to a local server 192.168.1.127.
curl -H "Content-type: application/json" -X POST
http:// 192.168.1.127:8080/bed -d
'{"command":{"value":3.012,"set":"target_pressure_voltage"},"id":2002,"side":"left","role":"command"}'
curl on the same box where the server is running is instant and the server does not complain.
A get request from the Android browser is fast. I have tried two Android devices with os version 4.x.
This question does not help as far as I can tell:
Android HttpURLConnection VERY slow
con.getInputStream() Takes ~20 sec:
String httpJson(String url, JSONObject job) {
String ret = null;
HttpURLConnection con = httpJsonCon(url);
if(con!=null)
httpJsonCon(con, url,job);
return ret;
}
HttpURLConnection mkCon(String url) {
HttpURLConnection con = null;
URL u = null;
try {
u = new URL(url);
con = (HttpURLConnection) (u.openConnection());
con.setRequestMethod("POST");
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "text/plain");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
con.setDoInput(true);
con.connect();
} catch (Exception e) {
Log.w(TAG, " e= " + e);
if(con!=null)
con.disconnect();
con = null;
}
return con;
}
String sendJson(HttpURLConnection con, JSONObject job) {
String ret = null;
if(con==null){
return ret;
}
try {
final String toWriteOut = job.toString();
final Writer out = new OutputStreamWriter(new BufferedOutputStream(
con.getOutputStream()), "UTF-8");
out.write(toWriteOut);
out.flush();
//con.getInputStream() Takes ~20 sec:
final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
} catch (IOException e) {
Log.d(TAG, " e= " + e);
ret = null;
} finally {
if(con!=null)
con.disconnect();
}
return ret;
}

Add a request header that specifies the post content length.
con.setRequestProperty("Content-Length", "" + json.length());

Related

Upload an attachment to azure devops [REST API]

I'm having a hard time adding a attachments in my azure devops repo via api...
public static void putAttachments(Integer id) {
try {
URL url = new URL(
"https://dev.azure.com/marcoparra0034/AgileFr/_apis/wit/attachments?api-version=5.1&fileName=imageAs.png");
HttpURLConnection con = ResApiMain.apiConnectionAttachments(PAT, url);
File file = new File("C:\\Users\\marco.parra\\Pictures\\Screenshots\\new.png");
String base64Image = encodeFileToBase64Binary(file);
// String jsonInputString = "[{\"op\":\"add\",\"path\":\"/fields/System.Title\",\"value\":\"" + "tpain"
// + "\"}]";
base64Image = "[" + base64Image + "]";
System.out.println("Base xs" + base64Image);
try (OutputStream os = con.getOutputStream()) {
byte[] input = Base64.decodeBase64(base64Image.getBytes("utf-8"));
System.out.println(new String(input));
os.write(input, 0, input.length);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
con.disconnect();
} catch (Exception ex) {
}
This is the connection method
public static HttpURLConnection apiConnectionAttachments(String PAT, URL url) {
HttpURLConnection con = null;
try {
String AuthStr = ":" + PAT;
Base64 base64 = new Base64();
String encodedPAT = new String(base64.encode(AuthStr.getBytes()));
con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Authorization", "Basic " + encodedPAT);
con.setDoOutput(true);
System.out.println("URL - " + url.toString());
System.out.println("PAT - " + encodedPAT);
// Image Requierements
// con.setRequestProperty("Content-Type", "image/jpeg");
con.setDoInput(true);
con.setUseCaches(false);
con.setRequestProperty("X-HTTP-Method-Override", "PATCH");
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/octet-stream");
// con.setRequestProperty("Accept", "application/json");
} catch (Exception e) {
System.out.println(e.getMessage());
}
return con;
}
When i run this it show the next error code
Server returned HTTP response code: 405 for URL: https://dev.azure.com/marcoparra0034/AgileFr/_apis/wit/attachments?api-version=5.1&fileName=imageAs.png
Update i see how to work with python and c# but i can´t follow this logic to create an attachment
https://github.com/Microsoft/azure-devops-python-api/blob/1bacd2a3f0128a6d184cf75e2c6f8859d46f270a/vsts/vsts/work_item_tracking/v4_1/work_item_tracking_client.py#L56
Expectations Example
{
"id": "a5cedde4-2dd5-4fcf-befe-fd0977dd3433",
"url": "https://dev.azure.com/fabrikam/_apis/wit/attachments/a5cedde4-2dd5-4fcf-befe-fd0977dd3433?fileName=imageAsFileAttachment.png"
}
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/attachments/create?view=azure-devops-rest-5.1
Any help would be appreciated....
I solve this issue commenting line con.setRequestProperty("X-HTTP-Method-Override", "PATCH");

Switch to POST method in java doesn't work

I can't understand how to switch to POST method in my HttpsURLConnection. On the debugger the request method is GET also after the setRequestMethod method. Can you tell me where is my mistake?
try {
URL url=new URL("https://smartmates.herokuapp.com");
HttpsURLConnection connection= (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
//I'll add some params here
connection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Thank you very much.
This is a piece of code that I use to POST the String mensaje and receiving rta.ToString(). I think that DoSetInput(true) is a mistake, because you want to send a POST (output) and, eventually, get a response.
`
String urlParametros = "<?xml version=\"1.0\"?>";
urlParametros = urlParametros + mensaje;
byte[] postDatos = urlParametros.getBytes(StandardCharsets.UTF_8);
try {
URL miurl = new URL(url);
con = (HttpURLConnection) miurl.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
//******…………..
con.setRequestProperty("User-Agent", "Java client");
con.setRequestProperty("Content-Type", "text/xml");
try (DataOutputStream datos = new DataOutputStream(con.getOutputStream())) {
datos.write(postDatos);
}
StringBuilder rta;
try (BufferedReader entrada = new BufferedReader(
new InputStreamReader(con.getInputStream()))) {
String linea;
rta = new StringBuilder();
while ((linea = entrada.readLine()) != null) {
rta.append(linea);
rta.append(System.lineSeparator());
}
}
return rta.toString();
} finally {
con.disconnect();
}´
Hope it helps
Daniel

Java Bitstamp API market order File not Found

I am trying to make a post from Java to make a market order using my Bitstamp account but the following code is returning a file not found for the URL.
It may be because of CSRF but I am unsure, if anyone has had any experience with the bitstamp API that would be great.
public static void postToken() throws IOException, JSONException {
URL url = null;
String sig = encode();
try {
url = new URL("https://www.bitstamp.net/api/v2/buy/market/" + feedbackType.toLowerCase() +"usd/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);//5 secs
connection.setReadTimeout(5000);//5 secs
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
JSONObject cred = new JSONObject();
cred.put("key",api_key);
cred.put("signature", sig);
cred.put("nonce", nonce);
cred.put("amount", feedback);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(cred.toString());
out.flush();
out.close();
int res = connection.getResponseCode();
System.out.println(res);
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while((line = br.readLine() ) != null) {
Log.d(TAG, line);
}
connection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Error: W/System.err: java.io.FileNotFoundException: https://www.bitstamp.net/api/v2/buy/market/btcusd/

HttpURLConnection 403 response after 200

Ok so I'm working on an app with 2 activities.
Let's call the 1st one LoginActivity which appears on top of my MainActivity. Also, I have a class SenderReceiver which extends AsyncTask that takes care of the connection to my https server.
The 1st time I call SenderReceiver from my LoginActivity, everything works fine & I get a 200 response & I'm able to use the JSON retrieved.
After that, the LoginActivity finishes & returns a result to the MainActivity. This is when I know I'm logged in & I can proceed.
Now whenever I execute SenderReceiver to get other information, I get the 403 response with a java.io.FileNotFoundException: https://url_of_my_server. But if I call the login again, it works.
Below is the SenderReceiver code snippet which connects to the server.
I'm also connecting to the same server on the iOS version of the app & never have issues with subsequent calls after the login.
Now this is my 1st time using https connections & such, I'm not really sure how it works on Android so I must be missing something or doing something wrong.
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0]; // For later
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
is = conn.getInputStream();
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}
Fixed it!
All I had to do was to set the cookie header with:
conn.setRequestProperty("Cookie", Constants.kCookies);
& retrieve that cookie after the response in order to set it with:
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
That way in the initial HttpURLConnection connections (i.e:login) the cookie is empty & not needed. Once a connection is successful (after "login") it receives the cookie & sets it.
After that, any subsequent connection sends that cookie as part of the header.
The updated method below:
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0];
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
// Get the cookie from my Constants file & set it, Constants.kCookies is a static String
conn.setRequestProperty("Cookie", Constants.kCookies);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
Constants.Log("The response code is: " + responseCode);
is = conn.getInputStream();
// Retrieve the cookie from the response & if not null save it to Constants.kCookies
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();//readIt(is, len);
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}

How to stream a JSON object to a HttpURLConnection POST request

I can not see what is wrong with this code:
JSONObject msg; //passed in as a parameter to this method
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setRequestProperty( "Content-Type", "application/json" );
httpCon.setRequestProperty("Accept", "application/json");
httpCon.setRequestMethod("POST");
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
msg.write(osw);
osw.flush();
osw.close();
os.close(); //probably overkill
On the server, I am getting no post content at all, a zero length string.
Try
...
httpCon.setRequestMethod("POST");
httpCon.connect(); // Note the connect() here
...
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
...
osw.write(msg.toString());
osw.flush();
osw.close();
to send data.
to retrieve data try:
BufferedReader br = new BufferedReader(new InputStreamReader( httpCon.getInputStream(),"utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
System.out.println(""+sb.toString());
public String sendHTTPData(String urlpath, JSONObject json) {
HttpURLConnection connection = null;
try {
URL url=new URL(urlpath);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
OutputStreamWriter streamWriter = new OutputStreamWriter(connection.getOutputStream());
streamWriter.write(json.toString());
streamWriter.flush();
StringBuilder stringBuilder = new StringBuilder();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
InputStreamReader streamReader = new InputStreamReader(connection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(streamReader);
String response = null;
while ((response = bufferedReader.readLine()) != null) {
stringBuilder.append(response + "\n");
}
bufferedReader.close();
Log.d("test", stringBuilder.toString());
return stringBuilder.toString();
} else {
Log.e("test", connection.getResponseMessage());
return null;
}
} catch (Exception exception){
Log.e("test", exception.toString());
return null;
} finally {
if (connection != null){
connection.disconnect();
}
}
}`
call this methopd in doitbackground in asynctask
HttpURLConnection is cumbersome to use. With DavidWebb, a tiny wrapper around HttpURLConnection, you can write it like this:
JSONObject msg; //passed in as a parameter to this method
Webb webb = Webb.create();
JSONObject result = webb.post("http://my-url/path/to/res")
.useCaches(false)
.body(msg)
.ensureSuccess()
.asJsonObject()
.getBody();
If you don't like it, there is a list of alternative libraries on the link provided.
Why should we all write the same boilerplate code every day? BTW the code above is more readable and less error-prone. HttpURLConnection has an awful interface. This has to be wrapped!
Follow this example:
public static PricesResponse getResponse(EventRequestRaw request) {
// String urlParameters = "param1=a&param2=b&param3=c";
String urlParameters = Piping.serialize(request);
HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);
PricesResponse response = null;
try {
// POST
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
// RESPONSE
BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
String json = Buffering.getString(reader);
response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);
writer.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
conn.disconnect();
System.out.println("PricesClient: " + response.toString());
return response;
}
public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {
return RestClient.getConnection(endPoint, "POST", urlParameters);
}
public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {
System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
HttpURLConnection conn = null;
try {
URL url = new URL(endPoint);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/plain");
} catch (IOException e) {
e.printStackTrace();
}
return conn;
}
this without json String post data to server
class PostLogin extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String response = null;
Uri.Builder builder= new Uri.Builder().appendQueryParameter("username","amit").appendQueryParameter("password", "amit");
String parm=builder.build().getEncodedQuery();
try
{
response = postData("your url here/",parm);
}catch (Exception e)
{
e.printStackTrace();
}
Log.d("test", "response string is:" + response);
return response;
}
}
private String postData(String path, String param)throws IOException {
StringBuffer response = null;
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
// connection.setRequestProperty("Content-Type", "application/json");
// connection.setRequestProperty("Accept", "application/json");
OutputStream out = connection.getOutputStream();
out.write(param.getBytes());
out.flush();
out.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
response = new StringBuffer();
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
}
return response.toString();
}

Categories

Resources