eeijlar eeijlar - 2 months ago 24
Java Question

Atlassian Confluence : how do I update page using REST API

I am trying to update a Confluence page using this code:
https://bitbucket.org/jaysee00/confluence-rest-api-example/src/master/src/main/java/com/atlassian/api/examples/Main.java

Code is:

public class Confluence {
/**
* Demonstrates how to update a page using the Conflunence 5.5 REST API.
*/
private static final Logger LOGGER = Logger.getLogger(Confluence.class);;
private static final String BASE_URL = "http://confluence:8080";
private static final String USERNAME = "admin";
private static final String PASSWORD = "admin";
private static final String ENCODING = "utf-8";

private String getContentRestUrl(Long contentId, String[] expansions)
throws UnsupportedEncodingException {
String expand = URLEncoder.encode(StringUtils.join(expansions, ","),
ENCODING);

return String
.format("%s/rest/api/content/%s?expand=%s&os_authType=basic&os_username=%s&os_password=%s",
BASE_URL, contentId, expand,
URLEncoder.encode(USERNAME, ENCODING),
URLEncoder.encode(PASSWORD, ENCODING));
}

public void publish() throws ClientProtocolException, IOException, Exception {
final long pageId = 36307446;

HttpClient client = new DefaultHttpClient();

// Get current page version
String pageObj = null;
HttpEntity pageEntity = null;
try {
String restUrl = getContentRestUrl(pageId,
new String[] { "body.storage", "version", "ancestors" });
HttpGet getPageRequest = new HttpGet(restUrl);
HttpResponse getPageResponse = client.execute(getPageRequest);
pageEntity = getPageResponse.getEntity();

pageObj = IOUtils.toString(pageEntity.getContent());

LOGGER.info("Get Page Request returned "
+ getPageResponse.getStatusLine().toString());
LOGGER.info(pageObj);
LOGGER.info((int)pageObj.trim().charAt(0));
} finally {
if (pageEntity != null) {
EntityUtils.consume(pageEntity);
}
}

// Parse response into JSON
JSONObject page = new JSONObject(pageObj.trim());

// Update page
// The updated value must be Confluence Storage Format
// NOT HTML.
page.getJSONObject("body").getJSONObject("storage")
.put("value", "hello, world");

int currentVersion = page.getJSONObject("version").getInt("number");
page.getJSONObject("version").put("number", currentVersion + 1);

// Send update request
HttpEntity putPageEntity = null;

try {
HttpPut putPageRequest = new HttpPut(getContentRestUrl(pageId,
new String[] {}));

StringEntity entity = new StringEntity(page.toString());
entity.setContentType("application/json");
putPageRequest.setEntity(entity);

HttpResponse putPageResponse = client.execute(putPageRequest);
putPageEntity = putPageResponse.getEntity();

System.out.println("Put Page Request returned "
+ putPageResponse.getStatusLine().toString());
System.out.println("");
System.out.println(IOUtils.toString(putPageEntity.getContent()));
} finally {
EntityUtils.consume(putPageEntity);
}
}


}

The response is alway 'HTTP 404 - Page not found'. I have changed the page id to one I know exists in Confluence.

An exception follows when it tries to parse the response into a JSON object:

avvvaorg.json.JSONException: A JSONObject text must begin with '{' at character 1
at org.json.JSONTokener.syntaxError(JSONTokener.java:496)
at org.json.JSONObject.<init>(JSONObject.java:180)
at org.json.JSONObject.<init>(JSONObject.java:403)
at com.openet.report.publish.Confluence.publish(Confluence.java:74)
at com.openet.report.miner.ReportMiner.generateSummary(ReportMiner.java:268)
at com.openet.report.miner.ReportMiner.runReport(ReportMiner.java:251)
at com.openet.report.miner.ReportMiner.main(ReportMiner.java:138)

Answer

Updating confluence pages using REST is not supported by Confluence 4.3.1. The API is much more limited: https://docs.atlassian.com/atlassian-confluence/REST/4.3.1/

You can however update confluence using XML RPC:

public void publish() throws IOException {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    Date today = Calendar.getInstance().getTime(); 
    XWikiXmlRpcClient rpc = new XWikiXmlRpcClient(CONFLUENCE_URI);
    try {
        rpc.login(USER_NAME, PASSWORD);
        //The info macro would get rendered an info box in the Page
        Page page = new Page();
        page.setSpace("Some space");
        page.setTitle("Testing XML RPC calls in confluence_" + df.format(today));            
        //page.setContent(
        String s = String.format("||Heading 1||Heading 2||Heading 3||%s|col A1|col A2|col A3|", "\r\n");
        page.setContent(s);
        page.setParentId(PAGEID);            
        rpc.storePage(page);
        } catch (XmlRpcException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

            // TODO Auto-generated catch block

}

This requires the following libraries:

import org.apache.xmlrpc.XmlRpcException;
import org.codehaus.swizzle.confluence.Page;
import org.w3c.dom.Document;
import org.xwiki.xmlrpc.XWikiXmlRpcClient;

Note that these libraries are not in the standard maven repository. You will have to update your repository manager (artifactory in my case) to sync with the XWiki maven repo. You will also need the service rocket plugin (https://community.servicerocket.com/servicerocket/topics/the-license-could-not-be-verified-there-is-no-license-certificate-installed-for-customware-scaffolding-plugin-for-confluence) configured correctly on Confluence.