I have a Drupal 6.10 site and a home-grown Java webapp. They need to talk to eachother. Getting Drupal to talk to Java is pretty easy as I can build whatever interface I want into the Java webapp. Going the other way (Java to Drupal) is what I will discuss in this article.

First, you have to have Services enabled on your Drupal installation. I'm also using an API key (you have to configure this in Drupal).

Here's the Java code I used to connect:

import org.apache.xmlrpc.client.*;
 
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.binary.Hex;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
 
import java.net.URL;
import java.security.SignatureException;
import java.util.HashMap;
import java.util.Map;
 
public class T {
    public static final String domain = "example.com"; // As set in Drupal
    public static final String apiKey = "0c77a3db905bc70f7cdfec049601c0bf"; // As found in drupal
 
    public static void main(String[] args) throws Exception {
 
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL("http://example.com/services/xmlrpc"));
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
 
        Object[] params = null;
        Object result = null;
        long timestamp = 0;
 
        params = new Object[] {};
        result = client.execute("system.listMethods", params);
        printResult(result);
 
        params = new Object[] {};
        result = client.execute("system.connect", params);
        printResult(result);
        String sessid = (String) ((Map) result).get("sessid");
 
        timestamp = System.currentTimeMillis() / 1000;
        String randomString = randomString();
        String data = timestamp + ";" + domain + ";" + randomString + ";" + "user.login";
        String hash = calcHMACSHA256(data, apiKey);
        params = new Object[] {hash, domain, String.valueOf(timestamp), randomString, sessid, "scott", "tiger"};
        result = client.execute("user.login", params);
        printResult(result);
        sessid = (String) ((Map) result).get("sessid");
 
        timestamp = System.currentTimeMillis() / 1000;
        randomString = randomString();
        data = timestamp + ";" + domain + ";" + randomString + ";" + "user.save";
        hash = calcHMACSHA256(data, apiKey);
        Map user = new HashMap();
        user.put("uid", 76196);
        user.put("mail", "ian@1321.org3");
        params = new Object[] {hash, domain, String.valueOf(timestamp), randomString, sessid, user};
        result = client.execute("user.save", params);
        printResult(result);
    }
 
    public static void printResult(Object result) {
        System.out.println(result.getClass());
        if (result.getClass().isArray()) {
            for (Object o : (Object[]) result) {
                System.out.println(o);
            }
        } else {
            System.out.println(result);
        }
    }
 
    private static String randomString() {
        return DigestUtils.md5Hex(String.valueOf(System.currentTimeMillis()));
    }
 
    private static String calcHMACSHA256(String data, String key) throws Exception {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(data.getBytes());
 
        return Hex.encodeHexString(rawHmac);
    }
}

I'm using commons-codec-1.4 and apache-xmlrcp-3.1.2. The code is not pretty (yet), but it works.

Powered by Drupal, an open source content management system

Navigation