Submitted by ian on Thu, 08/20/2009 - 07:25
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.
- ian's blog
- Login or register to post comments