HTTP PUT Request to Bitbucket API - java

I want to develop a java library for bitbucket issues API access.
I've already asked a question about the computation of the HTTP Content-Length header, but this question is specifically about the Bitbucket API and the process of updating an issue (since every other request works well).
The following code doesn't work, giving a 411 Length Required error.
But even more confusing: In the documentation, you are told to use PUT request method. If you "forget" to specify that, status code changes to 200 OK, but leaving the issue unchanged.
public class PutTest {
public static void main(String[] args) throws Exception {
URL u = new URL("https://api.bitbucket.org/1.0/repositories/myname/myproject/issues/1/?title=hello+world");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.addRequestProperty("Authorization", "Basic "+Base64.encodeToString("user:password".getBytes(), false));
c.addRequestProperty("Content-Length", String.valueOf(u.getQuery().getBytes("UTF-8").length));
c.setRequestMethod("PUT");
c.connect();
System.out.println(c.getResponseCode()+" "+c.getResponseMessage());
}
}

My updated code sample works, with help of another question at stackoverflow: How to send PUT, DELETE HTTP request in HttpURLConnection? Looks like not working.
Utilizing connection's OutputStream works.
public class PutTest {
public static void main(String[] args) throws Exception {
URL u = new URL("https://api.bitbucket.org/1.0/repositories/myname/myproject/issues/1/");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.addRequestProperty("Authorization", "Basic "+Base64.encodeToString(("user:password").getBytes(), false));
c.setRequestMethod("PUT");
c.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(c.getOutputStream());
out.write("title=hello+world");
out.close();
c.connect();
System.out.println(c.getResponseCode()+" "+c.getResponseMessage());
}
}

Related

HttpUrlConnect not sending a post request as part of a thread

I'm trying to send a http post request as part of a concurrent thread to an application launch.
The code below shows the current code I have now. I tried using the code from Baeldung and similar tutorial sites but I can't seem to get this working.
public static void main(String[] args) throws Exception {
HttpURLConnection con = (HttpURLConnection) new URL("http://localhost:5000/").openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setDoOutput(true);
String jsonInputString = "{\"status\": \"UP\"}";
OutputStream os = con.getOutputStream();
//random code here not involved with this quesiton
new Thread(new Runnable() {
public void run() {
while (true) {
try {
os.write(jsonInputString.getBytes());
os.flush();
}
catch (Exception exception) {
System.out.println("Its not working");
}
}
}
}).start();
launch(args);
When I go to type in localhost:5000 in a browser it says it can't connect.
First step make sure local host is working on port 5000, go to http://localhost:5000/ in a regular browser, if thats not working you need to make sure your machine is serving a page on port 5000 properly.
If thats working, the HTTP request may be getting blocked because its not connecting to a server with a valid SSL certificate, you can try changing the webpage to http://www.google.com and see if it gets a response.

Is it really necessary to use url.openConnection()?

As we all know both these codes will yield the same result
public class MainApp {
public static void main(String[] args) throws IOException {
URL google = new URL("http://www.google.com");
google.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(google.openStream()));
reader.lines().forEach(System.out::println);
}
}
and
public class MainApp {
public static void main(String[] args) throws IOException {
URL google = new URL("http://www.google.com");
BufferedReader reader = new BufferedReader(new InputStreamReader(google.openStream()));
reader.lines().forEach(System.out::println);
}
}
So what's the point in using google.openConnection()?
May be javadoc for this method helps:
public java.net.URLConnection openConnection() throws java.io.IOException
Returns a URLConnection instance that represents a connection to the remote object referred to by the URL. A new instance
of URLConnection is created every time when invoking the
URLStreamHandler.openConnection(URL) method of the protocol handler
for this URL.
It should be noted that a URLConnection instance does not establish
the actual network connection on creation. This will happen only when
calling URLConnection.connect().
If for the URL's protocol (such as HTTP or JAR), there exists a
public, specialized URLConnection subclass belonging to one of the
following packages or one of their subpackages: java.lang, java.io,
java.util, java.net, the connection returned will be of that subclass.
For example, for HTTP an HttpURLConnection will be returned, and for
JAR a JarURLConnection will be returned.
Use this if you want to add some specific connectivity properties to your connection.
For example:
URLConnection urlConnection = google.openConnection();
urlConnection.setReadTimeout(1000);
urlConnection.setConnectTimeout(1000);
Since the code for openStream() is:
public final InputStream openStream() throws java.io.IOException {
return openConnection().getInputStream();
}
It seems quite redundant indeed.
But if I were you, if I openConnection()d, I would then get the InputStream on the returned URLConnection.
openConnection() does not modify the URL object, it returns a URLConnection instance that you could then use. The code in the question ignores the return value of openConnection(), so, in this case, it's indeed pointless. it would only be useful if you actually do something with this connection object, such as, e.g., modifying its timeout:
URL google = new URL("http://www.google.com");
URLConnection conn = google.openConnection();
conn.setTimeout(7); // just an example
BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
reader.lines().forEach(System.out::println);

Sending POST JSON data using HttpURLConnection and AsyncTask

I'm trying to send some JSON data (if its a problem it may be a normal string) but it's not working at all.
When I add getResponseCode it sends POST with empty body to the server but the headers are set (Content-Type - application/json). I tried on many different ways but there is always empty body. Can someone look at it? I feel like I am missing something important...
//when button is tapped:
final String url = "http://postcatcher.in/catchers/";
new AsyncHttpTask().execute(url);
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/json");
// conn.getResponseCode
JSONObject jsonParam = new JSONObject();
jsonParam.put("name", "Andrew");
jsonParam.put("code", "5412274");
OutputStreamWriter os = new OutputStreamWriter(conn.getOutputStream());
os.write(jsonParam.toString());
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
The thing is that when I am using that conn.getResponse Code I'm sure that there is connection with server but the body is empty.
When i delete it, the POST message are not sending at all (seems that it is not working)
On that place you have not send anything yet so you cannot expect a response. You will have an IOException for that then. Log it and look in the logcat. If you want to know the response you should put it after you have send all. So after os.flush(). But you are not reading the response. The webserver will send something back isn't it? You are not reading that from conn.getInputStream(). Read it otherwise you will never know what the catcher answers.

using Get request with URLConnection

I am currently writing program to communicate with a device in my network, and the following code is what I have so far, it passed authentication and can get the webpage from the device, however i couldnt get the GET request to work, when I run the code below, i get the error:
Exception in thread "main" java.io.FileNotFoundException: http://192.168.100.222:80
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
when I input data on the webpage, its equivalent of going http://l192.168.xxx.xxx/2?A=3&p=1&X=1234, and from tcpflow, it does GET /2?A=4&p=1&X=1234 HTTP/1.1,
I tried creating a new url connection with http://192.168.xxx.xxx/2?A=3&p=1&X=1234, and it worked, but i have multiple input options and i dont want to create a new connection for each of them, how can I do the equivalent while staying connected? or what I did wrong in the code?
thanks in advance.
public class main {
public static void main(String[] argv) throws Exception {
Authenticator.setDefault(new MyAuthenticator());
URL url = new URL("http://192.168.xxx.xxx");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("Get /2?A=4&p=1&X=1234 HTTP1.1");
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
I don't want to create a new connection for each of them
Don't worry about that. HttpURLConnection does connection pooling under the hood. Just use your actual URLs, don't try to out-think Java.

Http POST in BlackBerry

Greetings,
I am trying to setup a server connection from my BlackBerry Application . I was able to get a response code on the status of the server. Now i have a few values which i have to POST to the server
Its like a registration page values(username, password, age ) have to be sent to the server .
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
if (connDesc != null)
{
HttpConnection httpConn;
httpConn = (HttpConnection)connDesc.getConnection();
try
{
final int iResponseCode = httpConn.getResponseCode();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Response code: " + Integer.toString(iResponseCode));
}
});
}
catch (IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
}
}
Thats the code i used to get the response code.
I would appreciate it if someone could help me how i can make a POST request to the server..
the server url for status was company.com/app/version/stats
when it for register it would be
company.com/app/register
Thank you
What type of a POST do you use? If you are just passing key-value pairs, then it should be a POST of a "application/x-www-form-urlencoded" content-type.
So, what lacks youe code is:
1). Set a proper content-type on your connection:
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
2). Prepare the content to be sent to the server via the POST:
URLEncodedPostData encPostData = new URLEncodedPostData("UTF-8", false);
encPostData.append("username", username);
encPostData.append("password", password);
encPostData.append("age", age);
byte[] postData = encPostData.toString().getBytes("UTF-8");
3). Set content-length for the connection (this step may be optional - try without this first, probably the BB OS is smart enough to set this automatically):
httpConn.setRequestProperty("Content-Length", String.valueOf(postData.length));
4). Open an OutputStream and write the content to it (the code is simplified):
OutputStream os = httpConn.openOutputStream();
os.write(postData);
os.flush();
...
httpConn = (HttpConnection)connDesc.getConnection();
httpConn.setRequestMethod(HttpConnection.POST);
httpConn.setRequestProperty("username",name);
httpConn.setRequestProperty("password",pass);
....

Categories