How to not close an HttpsURLConnectios after writing or reading DataStream - java

how could I get connection alive after follows operation in Java:
private static void makePostRequestAndPrintContent(String payload) throws IOException, InterruptedException{
URL url = new URL("url");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setInstanceFollowRedirects(true);
con.setRequestMethod("POST");
try( DataOutputStream wr = new DataOutputStream(con.getOutputStream())){
wr.write(convertPayloadToBytes(payload));
}
printContent(con);
}
printcontent():
private static void printContent(HttpsURLConnection con) throws InterruptedException{
if(con!=null){
try {
System.out.println("****** Content of the URL ********");
String input;
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
while ((input = br.readLine()) != null){
System.out.println(input);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
After posting the payload I have to wait some time for PUT-response from the Server, but after execution of post-request and reading content from redirect-site, connection will be immediately closed (at least an app will be terminated).
How to set connection to wait for further responses and then read InputStream again?

Related

Java: Cannot write to a URLConnection if doOutput=false - call setDoOutput(true)

I'm a QA with desire to learn more about Java programming and problem I'm experiencing is this:
I'm trying to POST Employee data to the database of some fake Rest API, but I'm getting
Cannot write to a URLConnection if doOutput=false - call
setDoOutput(true)"
So far, I tried some ideas from StackOverflow, but inexperienced as I am, I could easily fall deeper into a problem.
So URL is: http://dummy.restapiexample.com/api/v1/create and firstly I created an Employee class of json object:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
// URLConnection urlc = url.openConnection();
// urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Well, using one of your ideas and added next lines of code (it's commented in above code):
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
So the code looks like:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(urlc.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(urlc.getInputStream())));
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace(); }
catch (IOException e) {
e.printStackTrace();
}
}}
With this second code I'm not getting that error, but there is no inserting to the database(checking that using postman, with GET method)...
Well, what am I missing? I guess, I'm missing something basic...
Using url.openConnection twice means you get two different connections. You send the request to the second connection, and try to read the response from the first connection. You should call doOutput on the connection you open originally.
The second problem is you're calling getResponseCode before the request is sent. In http, the request must be sent entirely before the server sends a response. You should move the code that calls doOutput and writes the request body before the code that tries to check the response code.

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/

Java - How to open one HttpURLConnection for both GET and POST

The request is to GET content from url and handle the content(different every time) properly, then POST the answer back to the same url. I encounter "Can't reset method: already connected" when I try to setRequestMethod("POST") after GET method executed. My code as below
public class MyClass {
/**
* #param args
*/
public MyClass() {};
public void process() {
String url = "http://www.somesite.com/";
String strPage = null;
int n = 0;
try{
URL urlObj = new URL(url);
HttpURLConnection urlConnection =
(HttpURLConnection)urlObj.openConnection();
InputStream in = urlConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String strWhole = null;
while(null != (strPage = reader.readLine())){
strWhole += strPage;
}
//handle content here and calculate result
... ...
//send result below
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
String urlParameters = "aa=bb&cc=dd&ee=ff";
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
InputStream in1 = urlConnection.getInputStream();
BufferedReader reader1 = new BufferedReader(new InputStreamReader(in));
while(null != (strPage = reader1.readLine())){
System.out.println(strPage);
}
reader1.close();
}
catch(Exception e){
String exception = e.getMessage();
System.out.println(exception);
if (reader != null) {
reader.close();
}
if (reader1 != null) {
reader1.close();
}
}
return;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyClass dp = new MyClass();
dp.process();
}
}
It is impossible to reuse HttpURLConnection instance. But documentation says that under the hood, Java reuses connections for you:
The JDK supports both HTTP/1.1 and HTTP/1.0 persistent connections.
When the application finishes reading the response body or when the application calls close() on the InputStream returned by URLConnection.getInputStream(), the JDK's HTTP protocol handler will try to clean up the connection and if successful, put the connection into a connection cache for reuse by future HTTP requests.
The support for HTTP keep-Alive is done transparently.
Therefore, there is no need to reuse connections manually.
You must set all parameters first. Here's a code i use in my application:
HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("app_token", "my token"); // optional header you can set with your own data
connection.setRequestProperty("charset", "utf-8");
connection.setRequestProperty("Content-Length", String.valueOf(urlParameters.getBytes().length));
connection.setUseCaches (false);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
connection.disconnect();
InputStream is = connection.getInputStream();
byte[] b = readWithoutSize(is);
is.close();
The readWithoutSize is:
public static byte[] readWithoutSize(InputStream is) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
byte[] buf = new byte[512];
int leu;
while ((leu = is.read(buf)) != -1)
baos.write(buf,0,leu);
return baos.toByteArray();
}

HttpURLConnection Error - java.io.IOException: Server returned HTTP response code: 400 for URL

I am trying to connect to a URL from a desktop app, and I get the error indicated in the Title of my question
Url:https://capi-eval.signnow.com/api/user
The Code fragment.
public void getUrl(String urlString) throws Exception
{
String postData=String.format("{{\"first_name\":\"%s\",\"last_name\":\"%s\",\"email\":\"%s\",\"password\":\"%s\"}}", "FIRST", "LAST","test#test.com","USER_1_PASSWORD");
URL url = new URL (urlString);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Length",""+postData.length());
connection.setRequestProperty ("Authorization", "Basic MGZjY2RiYzczNTgxY2EwZjliZjhjMzc5ZTZhOTY4MTM6MzcxOWExMjRiY2ZjMDNjNTM0ZDRmNWMwNWI1YTE5NmI=");
connection.setRequestMethod("POST");
connection.connect();
byte[] outputBytes =postData.getBytes("UTF-8");
OutputStream os = connection.getOutputStream();
os.write(outputBytes);
os.close();
InputStream is;
if (connection.getResponseCode() >= 400) {
is = connection.getErrorStream();
} else {
is = connection.getInputStream();
}
BufferedReader in =
new BufferedReader (new InputStreamReader (is));
String line;
while ((line = in.readLine()) != null) {
System.out.println (line);
}
}
public static void main(String[] arg) throws Exception
{
System.setProperty("jsse.enableSNIExtension", "false");
Test s = new Test();
s.getUrl("https://capi-eval.signnow.com/api/user");
}
When i dig in the response and print error Stream My output is ::
{"errors":[{"code":65536,"message":"Invalid payload"}]}
any help appreciated
thanks
Maybe something wrong caused by unecoding. Just have a try by using Base64.encode.

Java - URL Connection in Threads

I currently have a project where different parameters are requested from an online CGI file, and each request is supposed to be processed in different threads. When I run my code by itself it works great, however it doesn't seem to connect when I put it in a thread.
My code is below:
public void run() {
connect();
}
public synchronized void connect(){
StringBuffer response = new StringBuffer("");
try {
String data = "year=" + year + "&top=" + numNames + "number=";
// Send data
URL url = new URL("http://www.ssa.gov/cgi-bin/popularnames.cgi");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
}
wr.close();
rd.close();
} catch (Exception e) {
System.out.println(e);
}
System.out.println(response);
}
}
Remove the synchronized call on connect. That should solve your problem
public synchronized void connect(){

Categories

Resources