Hello everyone!

I've been struggling for a day or two to get drupal_http_request() to function correctly with a custom Java HttpServlet I've written. The servlet never seemed to recieve the data I sent to it. Searching around on Google and drupal.org, I could not find decent documentation nor examples. I was using the following code from a custom Drupal module, using hook_nodeapi() tying into the 'update' action:


$url = http://localhost:8080/myservlet;

$headers = array();
			
$data = array (
	'key' => 'A160FDE523826CD438260CABFCD43892DCA75'),
	'id' => $node->nid,
	'action' => $action
	);
				
$response = drupal_http_request($url, $headers, 'POST', http_build_query($data));

Notice how I chose not to send any additional headers with the drupal_http_request() call. However, to correctly do a POST call there has to be a header called 'Content-Type' set to 'application/x-www-form-urlencoded'. Normally, this is done by default. I said Normally, so not in this case ;-)

To do a correct POST with simple form data, we can easily fix the above code as follows:


$url = http://localhost:8080/myservlet;

$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
			
$data = array (
	'key' => 'A160FDE523826CD438260CABFCD43892DCA75'),
	'id' => $node->nid,
	'action' => $action
	);
				
$response = drupal_http_request($url, $headers, 'POST', http_build_query($data));

If you're not familiar with http_build_query(), you can read up on it here: http://be.php.net/http_build_query

You will now notice that your Java HttpServlet will be able to properly get the post data by using the common request.getParameter("paramName") call. Best practice to me seems to always include the 'Content-Type' header to avoid (future) problems.

If you're trying to send binary data to a servlet (images, documents, ...), the 'Content-Type' header needs to be set to 'multipart/form-data'. Be ware that binary data can only be submitted using POST!

I hope this will be of some help to anyone out there.

Cheers,

mlc

Comments

mlc-1’s picture

Guys/Gals,

I forgot to mention the following issue with http_build_query(): if the above code results in only the first value from the $data array being passed to your servlet, you can fix the code as follows:


$url = http://localhost:8080/myservlet;

$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
           
$data = array (
    'key' => 'A160FDE523826CD438260CABFCD43892DCA75'),
    'id' => $node->nid,
    'action' => $action
    );
               
$response = drupal_http_request($url, $headers, 'POST', http_build_query($data, '', '&'));

Although this should not be necessary if you read the docs on http_build_query(), I encountered problems and was able to fix it as above...

Cheers,

mlc

greg.harvey’s picture

Thank you for sharing! =)

fizk’s picture

Thanks!!! :)

darora’s picture

Thanks for the tips...
I have similar requirement such that when user logs on to the Drupal site, I need to post this user information to another form on different site. So basically, need to do multiple logins.
How can I use the code in this post to be called when user login using the Drupal default login page.
Or is there any other way I need to accomplish my requirement.

Thanks for the suggestions.

a.milkovsky’s picture

use drupal_http_build_query

coltrane’s picture

Thanks for this post!

You also have to be aware of what your argument separator is to get the correctly encoded string. As brought up at http://be.php.net/manual/en/function.http-build-query.php#74781.

In my case using http_build_query without any additional arguments the returned string was separated by &amp.

Shademan’s picture

exactly what i needed, thanks!

asad.hasan’s picture

Thank you so much for saving the day...i was using html_entity_decode() to get rid of & in the query string, but was still missing the headers. Very cool!

budda’s picture

Phew...
$headers = array('Content-Type' => 'application/x-www-form-urlencoded'); solved my problem. You would assume Drupals API function would sort out including that header if the $method is a POST. Ah well, thanks for the clear explanation here.

artwick’s picture

Exactly what I was looking for. Many thanks for the post!

jayrock’s picture

Help me sir please I don't have any idea how to use web service of other site in drupal help me please thanks..