From Java do PUT in BitBucket

java
rest-api

#1

We have a locally installed BitBucket server.
Im trying to do a PUT from a Java application with a new file.

Executing this curl code in the console works when I have a README.txt file in the same path, so I thought I just translate that into Java.

curl -X PUT -u user:pass -F content=@README.txt -F message=curl -F branch=master http://bitbucket.abc.com:7990/rest/api/1.0/projects/ABCD/repos/mystuff/browse/README.txt

My Java implementation looks like this:

        try {
            String url = "http://bitbucket.abc.com:7990/rest/api/1.0/projects/ABCD/repos/mystuff/myfile.txt";
            HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
            con.setRequestMethod("PUT");
            con.setDoOutput(true);
            con.setRequestProperty("branch","master");
            con.setRequestProperty("message","just a message");
            con.setRequestProperty("content","@myfile.txt");
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("Accept", "application/json");
            
            String user = "user";
            String pw = "pass";
            String encoded = Base64.getEncoder().encodeToString((user + ":" + pw).getBytes(StandardCharsets.UTF_8));
            con.setRequestProperty("Authorization", "Basic " + encoded);

            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
            writer.write("Write some stuff in the file that will be persisted in the file.");
            writer.flush();
            writer.close();
            con.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }

I don’t get any exception and the file does not end up in the BitBucket repository.
Can anyone see any obvious error in the code?

/Bill


#2

Hey Bill, there are some small things that aren’t correct

One of them is the URL, this should contain /browse like in your curl example which you don’t have in your java example, so this results in a 404.
Also the Content-Type should not be ‘application/json’ but multipart.
to see the exact request that you did with curl add the verbose flag -v

curl -X PUT -u user:pass -F content=@README.txt -F message=curl -F branch=master http://bitbucket.abc.com:7990/rest/api/1.0/projects/ABCD/repos/mystuff/browse/README.txt -v

Dealing with multipart is not easy so it’s common to use a library for it so it get’s easier to use.
This example below should work and is based on your first example

CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            //note that it the path contains browse after the repo-url
            String url = "http://bitbucket.abc.com:7990/rest/api/1.0/projects/ABCD/repos/mystuff/browse/myfile29.txt";
            String user = "user";
            String pw = "pass";

            HttpPut httpPut = new HttpPut(url);
            String encoding = Base64.getEncoder().encodeToString((user + ":" + pw).getBytes(StandardCharsets.UTF_8));

            httpPut.setHeader("Authorization", "Basic " + encoding);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("branch", new StringBody("master", ContentType.TEXT_PLAIN))
                    .addPart("content", new StringBody("file content, can be different than stringbody, just as example", ContentType.TEXT_PLAIN))
                    .addPart("message", new StringBody("commit message", ContentType.TEXT_PLAIN))
                    .build();

            httpPut.setEntity(reqEntity);
            CloseableHttpResponse response = httpclient.execute(httpPut);
        } finally {
            httpclient.close();
        }

Here is are some great examples on how to use multipart with java


I hope this will help you a bit

Kind regards

Tomas


#3

Brilliant Tomas!
It works, thank you very much.
/Bill