Search code examples
javaconfluenceconfluence-rest-api

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)

Solution

  • 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.