$ch = curl_init();
curl_setopt($ch, CURLOPT_FILE, $file);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $urls[$vidCount]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
So I have a cURL request that takes a URL and produces a file in the filesystem.
How do I emulate the above PHP cURL request in Java?
I have tried HttpURLConnection, but I am getting 403 Forbidden. The same call in cURL works properly. Is there some architecture difference between the two that I need to reconcile?
I believe it could be something in the headers that cURL might be setting automatically where Java is not. I'm not really sure but I would appreciate any advice I can get.
Thanks.
I am not sure why you trying to emulate PHP behavior in Java. If the end result is really what you need to reach, than use the Java HttpURLConnection or even URLConnection.
Related
I do not know Java and I haven't had success with Google or trial and error testing...
How would I write this with just using CURL on the command line for a RESTful API authentication? (a php or perl solution would also be okay)
This code is from documentation but I don't plan on using Java and need to translate it.
URL url = new URL("http://www.thingsandstuff.com/resfulness/post");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// i don't know if this is relevant to my question or not...
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// this is what i think might be the problem...
String userNamePassword = "myusername:mypassword";
userNamePassword =
new String(org.apache.commons.codec.binary.Base64.encodeBase64(userNamePassword
.getBytes()));
conn.setRequestProperty("Authorization", userNamePassword);
I always get a 401 unauthorized error.
I've been just playing with the header argument -H. I don't know if what I am doing is not working because I am truly not doing the authentication right or if it is something else. The data is xml and I am testing with something very simple/straightforward. I am assuming that even if my data/xml/post is incorrect, it would be returning an error instead of an unauthorized.
# bXl1c2VybmFtZTpteXBhc3N3b3Jk == myusername:mypassword base64 encoded....
curl -H "bXl1c2VybmFtZTpteXBhc3N3b3Jk" -d "<datums>" -X POST http://www.thingsandstuff/restfulness/post
curl -H "bXl1c2VybmFtZTpteXBhc3N3b3Jk" -d "<datums>" -X POST http://www.thingsandstuff/restfulness/post
# and like this... with encoded things and not encoded things...
curl -d "<datums>" -X POST http://user:password#www.thingsandstuff.com/restfulness/post
curl -u user:password -d "<datums>" -X POST http://www.thingsandstuff.com/restfulness/post
And for all three, I've tried encoding just the password, both together, both separately, neither... And I'm sure it doesn't help that my username does have a \ and the password does end in an ! but I think, when I'm not encoding them, I am escaping properly.
And the curl man page says that -d will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded, so that means I don't need to pass an additional header saying the content-type, right? Basically... I only partially know what I'm doing and it doesn't work and there are too many things I don't know about enough to isolate my issue or probably even correct it (yes, just enough to be dangerous).
The reason you are getting the 401 is the Authorization header needs a scheme prefix, in your case Basic
So currently you are sending
Authorization: <base64(username:password)>
But the web server expects
Authorization: Basic <base64(username:password)>
as described here
this change should work:
conn.setRequestProperty("Authorization", "Basic " + userNamePassword);
Okay, so this is what I ended up with...
curl -H "Authorization:dXNlclxuYW1lOnBhc3N3b3JkIQ==" -X POST -d 'data=%3C%3Fxml+version....' http://www.stuffandthings.com:8080/restfulness/post
So... username:password is base 64 encoded together. The data is encoded by ISO/IEC 8859-1 and prefixed with "data=" this particular set restful service.
I ended up putting it in PHP just because it was easier to test continuously that way. And this is what ended up working for that...
$user = 'user\\name';
$pass = 'password!';
$userpass = base64_encode($user.':'.$pass);
$url = 'http://www.thingsandstuff.com:8080/restfulness/post';
if (($handle = fopen("foo.csv", "r")) !== FALSE)
{
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
list($thing1,$thing2) = $data;
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<entry xmlns=\"http://purl.org/atom/ns#\">
<xml data goes here>
<ns:thing1>$param1</ns:thing1>
<ns:thing2>$param2</ns:thing2>
</xml data goes here>
</entry>";
$datums = 'data='.utf8_decode($xml);
$result = do_curl($url,$datums);
// not actually using the response at this
// point... just running through everything
var_dump($result);
}
fclose($handle);
}
function do_curl($url, $data) {
global $userpass, $user, $pass;
$ch = curl_init();
$header = array('Authorization:'.$userpass,
'Content-Type:application/x-www-form-urlencoded',
'Content-Length:'.strlen($data));
// this line was the last thing to be added before it worked
// i didn't try it again, removing the authentication in $header
// to see if this was the only thing actually needed...
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$pass);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, $header);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$hout = curl_getinfo($ch, CURLINFO_HEADER_OUT);
//echo "\n"; var_dump($hout); echo "\n";
curl_close($ch);
return array('status'=>$status, 'result'=>$result);
}
And If I var_dump($hout) from the do_curl function... the header actually sent was:
POST /resfulness/post HTTP/1.1
Authorization: Basic dXNlclxuYW1lOnBhc3N3b3JkIQ==
Host: www.thingsandstuff.com:8080
Accept: */*
Content-Length: 409
Content-Type: application/x-www-form-urlencoded
<?xml version="1.0" encoding="UTF-8" ?>
<entry xmlns="http://purl.org/atom/ns#">
<xml data goes here>
<ns:thing1>value1</ns:thing1>
<ns:thing2>value2</ns:thing2>
</xml data goes here>
</entry>
I'm recieving 'null' on my Params.
So far i've found people using "PathParams", "FormParams" and "QueryParams" on java to get their variables from the request, however in my case, using post i dont have PathParams, and for some reason FormParams and QueryParams are returning null as if i had never sent them. So i'd like help to solve this.
My php cURL POST request:
<?php
$url = "http://localhost:8080/TestRest/test/asd";
$params = "param1=val1¶m2=val2";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>
My java Web Service:
#Path("/test")
public class Streams {
#POST
#Path("/asd")
#Produces(MediaType.TEXT_PLAIN)
#Consumes({"application/x-www-form-urlencoded"})
public String addStream(#FormParam("param1") String param1,
#FormParam("param2") String param2) {
return "param1 = "+param1;
}
}
For some reason param1 is null.
What am i doing wrong?
I am going out on a limb and saying your problem may stem from this:
urlencode($params);
For instance: a=1&b=2&c=3 is perfectly valid.
urlencode('a=1&b=2&c=3') goes to this: a%3D1%26b%3D2%26c%3D3 and your webservice may not understand what it is your are passing. It is looking for a=...&b=...&c=... and you are not giving it any of that.
Try leaving off the urlencode() and seeing if it works. If it does, and you still want to ensure content like this&this is encoded properly, then you will need to parse the url parameters, encode them, and then recombine them for the post data.
I've been tasked to translate an api from php to java.
The problem is when I have to call to the Api, it uses the curl library, which I don't even know that well in php, and I'm having a hard time finding its equivalent java.
Looking through other post I saw that most people recommended to use httpConnection, but still I can't figure it out.
any help would be apreciated:
$ch = curl_init( $curlUrl );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true););
if (strtolower($this->httpmethod) == "post") curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
$this->output = curl_exec($ch);
curl_close($ch);
Thank you.
The standard entry point to HTTP requests in Java is java.net.URL. From there you can open a connection to the URL.
is there any method that I can retrieve data (eg, username and password) from PHP to a Java servlet? Thanks
Create a POST request in PHP:
Use cURL:
$ch = curl_init('http://www.example.com:8080/my-servlet/');
$data = '...' # the data you want to send
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
A better, more concise approach, using pecl_http:
$response = http_post_data('http://www.example.com:8080/my-servlet/', $data);
POST and GET pretty much do not depend on the language being used, so if I understand your question correctly, you can use either $_POST['var'] in PHP or request.getParameter("var") in Java on the page that receives the POST data.
These are the steps:
POST Form (file/image input) from the browser goes to a PHP server.
The PHP server then use fsockopen to a Java (GlassFish/Jersey) REST service, sending the image as content for more advanced imaging work to be done there, and returning the resulting image back to the PHP server (or returning only a URI to the image).
The PHP server then echos the result (img src= ..) back to the user in the HTML document.
Getting the image and all its attributes in the first step works great, but I need help setting up the headers correctly in the POST request from PHP to the web service.
Current code:
$fp = fsockopen("domain..", 80, $errno, $errstr, 30);
$contentlength = $_FILES["photo_file"]["size"];
$imageref = $_FILES["photo_file"]["tmp_name"];
$out = "POST /Uri to resource .. HTTP/1.1\r\n";
$out .= "Host: http://... \r\n";
$out .= "Connection: Keep-Alive\r\n";
$out .= "Content-type: multipart/mixed\r\n";
$out .= "Content-length: $contentlength\r\n\r\n";
$out .= "$imageref";
fwrite($fp, $out);
$theOutput;
while (!feof($fp))
{
$theOutput .= fgets($fp, 128);
}
echo $theOutput;
fclose($fp);
Which echoes to the browser: "HTTP/1.1 400 Bad Request Content-Type: text/html Content-Length: 717".
So I need better formed headers to get through to the REST web-method. And if I should achieve that does anyone know what paramaters to use in the jersey web-method to access the image?
For standard HTML forms its this:
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response getFullImage(#FormDataParam("photo_file") InputStream imageIS {..ImageIO.read(imageIS)..}
Would love suggestions to better architecture also for achieving this in HTML.
Cheers
You probably have problem with badly written request and should use cURL at first place (in php), basic example usage (with writing to the file) from manual page:
$ch = curl_init("http://www.example.com/");
$fp = fopen("example_homepage.txt", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
Another example for setting post data from curl_setopt() page:
$data = array('name' => 'Foo', 'file' => '#/home/user/test.png');
curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
And handling HTTP status codes via curl_getinfo():
if(curl_getinfo($c, CURLINFO_HTTP_CODE) === 200){
...
}
You also may set http headers manually:
curl_setopt($cURL,CURLOPT_HTTPHEADER,array (
"Content-Type: text/xml; charset=utf-8",
"Expect: 100-continue"
));