I am trying to use the HttpClient library (in order to call the Facebook API's REST end points) to obtain a session key and verify user...
My code is here:
RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations =
{ "classpath*:**/*applicationContext-test.xml" })
public class FacebookUserTest
{
final String API_KEY = "9e2568d68f182a2957878f3acedd9453";
final String SECRET = "f1298956895d39110be92a672e0d2284";
final String TOKEN = "aa0c41aa4532053e8d0097844ab9bc7d";
final String LOGIN = "http://www.facebook.com/login.php";
final String HOST = "http://www.facebook.com/restserver.php";
private static Logger log =
LoggerFactory.getLogger(FacebookUserTest.class);
protected FacebookUser FacebookUser;
#Test
public void testFindUserBySessionKey() throws Exception
{
loginToFacebook();
String sessionKey = getSessionKey();
}
public void loginToFacebook() throws Exception
{
HttpClient client = new HttpClient();
client.setParams(new HttpClientParams());
client.setState(new HttpState());
GetMethod get = new GetMethod(LOGIN + "?api_key=" + API_KEY
+ "&v=1.0&auth_token=" + TOKEN);
// Get login screen
client.executeMethod(get);
// Post credentials to login
PostMethod post = new PostMethod(LOGIN);
post.addParameter(new NameValuePair("api_key", API_KEY));
post.addParameter(new NameValuePair("v", "1.0"));
post.addParameter(new NameValuePair("auth_token", TOKEN));
post.addParameter(new NameValuePair("email", "user#email.com"));
post.addParameter(new NameValuePair("pass", "password"));
client.executeMethod(post);
}
public String getSessionKey() throws Exception
{
HttpClient client = new HttpClient();
// Obtain session key
String host = "http://www.facebook.com/restserver.php";
String sessSecret = "false";
String toMd = "api_key=" + API_KEY + "auth_token=" + TOKEN
+ "format=xmlgenerate_session_secret=" + sessSecret
+ "method=facebook.auth.getSessionv=1.0" + SECRET;
String md5 = Md5Utils.MD5(toMd);
PostMethod post = new PostMethod(HOST);
NameValuePair[] data = {
new NameValuePair("api_key", API_KEY),
new NameValuePair("auth_token", TOKEN),
new NameValuePair("format", "xml"),
new NameValuePair("generate_session_secret", SECRET),
new NameValuePair("method", "auth.getSession"),
new NameValuePair("sig", md5), new NameValuePair("v", "1.0")
};
post.setRequestBody(data);
post.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
post.setRequestHeader("User-Agent",
"Facebook API PHP5 Client 1.1 (curl) 5");
// execute method and handle any error responses.
client.executeMethod(post);
StringBuilder sb = new StringBuilder();
byte[] b = new byte[4096];
for (int n; (n = post.getResponseBodyAsStream().read(b)) != -1;)
{
sb.append(new String(b, 0, n));
}
String sessionId = sb.toString();
log.warn("Session Id: " + sessionId);
return sessionId;
}
}
When I run my JUnit test, this is what is printed from the console:
WARN : com.myapp.FacebookUserTest - Session Id:
<?xml version="1.0" encoding="UTF-8"?>
<error_response xmlns="http://api.facebook.com/1.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://api.facebook.com/1.0/
http://api.facebook.com/1.0/facebook.xsd">
<error_code>104</error_code>
<error_msg>Incorrect signature</error_msg>
<request_args list="true">
<arg>
<key>api_key</key>
<value>9e2568d68f182a2957878f3acedd9453</value>
</arg>
<arg>
<key>auth_token</key>
<value>aa0c41aa4532053e8d0097844ab9bc7d</value>
</arg>
<arg>
<key>format</key>
<value>xml</value>
</arg>
<arg>
<key>generate_session_secret</key>
<value>f1298956895d39110be92a672e0d2284</value>
</arg>
<arg>
<key>method</key>
<value>auth.getSession</value>
</arg>
<arg>
<key>sig</key>
<value>fcf80d658f35d66396ac521da7102782</value>
</arg>
<arg>
<key>v</key>
<value>1.0</value>
</arg>
</request_args>
</error_response>
Could it be my MD5Utils code:
public class Md5Utils
{
private static String convertToHex(byte[] data)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
}
while (two_halfs++ < 1);
}
return buf.toString();
}
public static String MD5(String text)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
byte[] md5hash = new byte[32];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
md5hash = md.digest();
return convertToHex(md5hash);
}
}
What am I possibly doing wrong to generate an incorrect signature?
Would really appreciate it if someone could help me or point me in the right direction...
Happy programming and thanks for reading!
Try this
string GenerateSignature(IDictionary<string, string> parameters)
{
StringBuilder signatureBuilder = new StringBuilder();
// Sort the keys of the method call in alphabetical order
List<string> keyList = ParameterDictionaryToList(parameters);
keyList.Sort();
// Append all the parameters to the signature input paramaters
foreach (string key in keyList)
signatureBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0}={1}", key, parameters[key]));
// Append the secret to the signature builder
signatureBuilder.Append(ConfigurationManager.AppSettings["FBApiSecret"]);
MD5 md5 = MD5.Create();
// Compute the MD5 hash of the signature builder
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signatureBuilder.ToString().Trim()));
// Reinitialize the signature builder to store the actual signature
signatureBuilder = new StringBuilder();
// Append the hash to the signature
foreach (byte hashByte in hash)
signatureBuilder.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture));
return signatureBuilder.ToString();
}
string CreateHTTPParameterList(IDictionary<string, string> parameterList)
{
StringBuilder queryBuilder = new StringBuilder();
parameterList.Add("api_key", ConfigurationManager.AppSettings["FBApiKey"]);
parameterList.Add("v", "1.0");
parameterList.Add("call_id", DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture));
parameterList.Add("sig", GenerateSignature(parameterList));
//parameterList.Add("sig", _sig);
// Build the query
foreach (KeyValuePair<string, string> kvp in parameterList)
{
queryBuilder.Append(kvp.Key);
queryBuilder.Append("=");
queryBuilder.Append(HttpUtility.UrlEncode(kvp.Value));
queryBuilder.Append("&");
}
queryBuilder.Remove(queryBuilder.Length - 1, 1);
return queryBuilder.ToString();
}
Example usage :
Dictionary<string, string> parameterList = new Dictionary<string, string>();
parameterList.Add("auth_token", authCode);
parameterList.Add("format", "json");
parameterList.Add("method", "facebook.auth.getSession");
string req = CreateHTTPParameterList(parameterList);
I tryed to copy / paste these codes from my old project.
I hope it will be help to you.
you have an error in your parameter you send in generate_session_secret your secret code , it must be true or false
you set:
new NameValuePair("generate_session_secret", SECRET),
there are conflict in your parameter that u set in post and the signature
Related
I need to convert string into base64 under Oreo api level.
I have the following code:
public String genAuthKey(String u, String p){
user = u;
pass = p;
key = user+":"+pass;
byte[] encodedBytes = new byte[0];
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
encodedBytes = Base64.getEncoder().encode(key.getBytes());
Log.e("VERSION IS","O");
}else{
encodedBytes = Base64.getEncoder().encodeToString(key.getBytes()).getBytes();
Log.e("VERSION LESS","O");
}
Log.e("key",new String(encodedBytes,Charset.forName("UTF-8")));
return new String(encodedBytes, Charset.forName("UTF-8"));
}
In else condition, I need code to convert and send the data properly. How can I do that?
first add this import
import android.util.Base64;
then replace your method with a version agnostic variant
public String genAuthKey(String u, String p) {
user = u;
pass = p;
key = user + ":" + pass;
byte[] encodedBytes = Base64.encode(key.getBytes(), Base64.DEFAULT);
Log.e("key", new String(encodedBytes, StandardCharsets.UTF_8));
return new String(encodedBytes, StandardCharsets.UTF_8);
}
Enjoy!
Try this code for encoding kotlin:
var encodedString = Base64.encode("Your String", Base64.DEFAULT).toString(Charsets.UTF_8)
and for decoding:
var decodedString = Base64.decode(encodedString, Base64.DEFAULT).toString(Charsets.UTF_8)
so learning still but i'm getting an Error 401 unauthorised back from the code below. I know that the OAuth header works as it works in postman so i'm assuming there is a problem with the POST request / Auth header? Any ideas?
//set timestamp
Long timestamp = System.currentTimeMillis()/1000;
//set nonce ***** call from main system*************************************************************
String aString = randomAlphaNumeric(11);
// other stuff
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
String url = "aURL";
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// String auth = Base64.getEncoder().encodeToString(credentials.getBytes());
List<NameValuePair> oauthHeaders = new ArrayList<>(9);
oauthHeaders.add(new BasicNameValuePair("oauth_consumer_key", "aKey"));
oauthHeaders.add(new BasicNameValuePair("oauth_nonce", aString));
oauthHeaders.add(new BasicNameValuePair("oauth_timestamp", String.valueOf(timestamp)));
oauthHeaders.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
oauthHeaders.add(new BasicNameValuePair("oauth_version", "1.0"));
//generate signature
//encode
String encodedURL = encode(oauthHeaders.toString());
System.out.println("encoded URL:" +encodedURL);
//form base string
String baseString = "POST&"+encode(url).toString()+encodedURL;
System.out.println("Base String: "+baseString);
//form signature
byte[] byteHMAC = null;
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec spec;
if (null == secretKey) {
String signingKey = encode(secretKey) + '&';
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
} else {
String signingKey = encode(secretKey) + '&' + encode(secretKey);
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
}
mac.init(spec);
byteHMAC = mac.doFinal(baseString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
String signature = new BASE64Encoder().encode(byteHMAC);
System.out.println("oauth signature: "+signature);
//set signature to params
oauthHeaders.add(new BasicNameValuePair("oauth_signature", signature));
String test = "OAuth "+oauthHeaders.toString();
headers.set("Authorization", test);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("Name",name.toString());
map.add("Region",region.toString());
HttpEntity<MultiValueMap<String, String>> requestEntity= new HttpEntity<MultiValueMap<String, String>>(headers, map);
System.out.println(requestEntity);
ResponseEntity<String> response= restTemplate.exchange(url ,HttpMethod.POST, requestEntity, String.class);
System.out.println(response.toString());
HttpStatus status = response.getStatusCode();
status.toString();
if(status.equals("200")){
Notification.show("Employer" + name +" added successfully");
}
else{
Notification.show("Unsuccessful, error: "+status);
}
}
removed the URL and consumer key / signature for obvious reasons.
The following System out prints might help as well:
encoded params:
%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
Base String: POST&https%3A%2F%2Fapi.test.payrun.io%2FEmployer%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
oauth signature: DlRJGSzgRIItzz+LzMbgnIfbOqU=
The value of oauth_signature is wrong. You are using asignature as the value of oauth_signature, but you have to compute the correct value for your request and set it to oauth_signature. If the value of oauth_signature is wrong, the server will reject your request. See "3.4. Signature" in RFC 5849 (The OAuth 1.0 Protocol) for details.
For anyone who wants to make this work then please see below for a complete OAuth Generator example :):
public class oAuthGenerator {
private String httpMethod;
private String params;
private String url;
//Required for percent encoding
private static final String ENC = "ASCII";
//Required for nonce
private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
//As provided by Payrun.io
private static final String secretKey = "aSecretKey";
//As provided by Payrun.io
private static final String consumerKey ="aConsumerKey";
private List veriList;
//Constructor for setting signature base string values.
//#Param url needs to be percent encoded
//#Param params needs to be percent encoded, this is done #Method generateOAuth()
public oAuthGenerator(String httpMethod,String url )throws Exception {
veriList= new ArrayList<String>();
veriList.add("POST");
veriList.add("GET");
veriList.add("PUT");
veriList.add("DELETE");
if (veriList.contains(httpMethod)){
this.httpMethod = httpMethod+"&";}
this.url = URLEncoder.encode(url,ENC)+"&";
}
//A method used to generate the OAuth Authorization header
//#Method randomAlphaNumeric() calls internal method using instance variable ALPHA_NUMERIC_STRING
//#Method getSignature() returns String HMACSHA1 > Base64 encoded value of httpMethod,url,params
public String generateOAuth()throws Exception{
//Set timestamp as seconds from 01-01-1970
Timestamp timestamp = new Timestamp(System.currentTimeMillis()/1000);
Long aTimestamp = timestamp.getTime();
//Set nonce which is a 10 digit random, non repeating alpha-numeric value
String aNonce = randomAlphaNumeric(10);
//Normalize and form param string
String normalizedParams = "oauth_consumer_key="+consumerKey+"&"+"oauth_nonce="+aNonce+"&"+"oauth_signature_method="+"HMAC-SHA1"+"&"+"oauth_timestamp="+ aTimestamp.toString()+"&"+"oauth_version="+"1.0";
//Percent encoded params
params = URLEncoder.encode(normalizedParams,ENC);
//Set signature variable
String signature = getSignature();
//place into required format
String oAuthResult = "OAuth "+"oauth_version="+"\"1.0\""+","+"oauth_consumer_key="+"\"" + consumerKey + "\""+","+"oauth_signature_method="+"\"HMAC-SHA1\""+","+"oauth_timestamp="+"\""+aTimestamp+"\""+","+"oauth_nonce="+"\""+aNonce+"\""+","+"oauth_signature="+"\""+signature+"\"";
return oAuthResult;
}
// A method designed to return a hashed and base64 encoded value.
//#Param aString holds HMAC-SHA1 and Base 64 encoded value of variables httpMethod,url,params
//#Param result holds percent encoded value of aString
private String getSignature()
throws Exception {
//form base string
StringBuilder base = new StringBuilder();
base.append(httpMethod);
base.append(url);
base.append(params);
//Set SecretKey of variable secretKey using HMAC-SHA1 algorithm
SecretKey signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
// Get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
// Compute the hmac on input data bytes, then encode to Base64
String aString = Base64.getEncoder().encodeToString(mac.doFinal(base.toString().getBytes(ENC))).trim();
//Percent encoded the Base64 value
String result = URLEncoder.encode(aString, ENC);
return new String(result);
}
//Required for nonce, returns a random alpha numeric value by using variable ALPHA_NUMERIC_STRING
private static String randomAlphaNumeric(int count) {
StringBuilder builder = new StringBuilder();
while (count-- != 0) {
int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
builder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return builder.toString();
}
}
Here is the code that calls three functions from my custom java class:
QAndroidJniObject datafile = QAndroidJniObject::fromString(path);
QAndroidJniObject password = QAndroidJniObject::fromString("asimpletest");
QAndroidJniObject::callStaticObjectMethod("org/qcolocrypt/AESCrypt",
"AESCryptInit",
"(Ljava/lang/String;Ljava/lang/String;)V;",
password.object<jstring>(),
datafile.object<jstring>());
QAndroidJniObject decrypted_data = QAndroidJniObject::callStaticObjectMethod("org/qcolocrypt/AESCrypt",
"decrypt",
"()Ljava/lang/String;");
QAndroidJniObject fname = QAndroidJniObject::callStaticObjectMethod("org/qcolocrypt/AESCrypt",
"getFilename",
"()Ljava/lang/String;");
QAndroidJniObject status = QAndroidJniObject::callStaticObjectMethod("org/qcolocrypt/AESCrypt",
"getStatus",
"()Ljava/lang/String;");
Here is the java code for three of these functions:
The non working one:
public static void AESCryptInit (String passwd, String datafile){
// Initializing variables.
rawdata = null;
status = "";
fileName = datafile;
Log.i("[QCOLOCRYPT]","The filename is " + datafile);
// Transforming the passwd to 16 bytes.
try {
MessageDigest digester = MessageDigest.getInstance("MD5");
InputStream in = new ByteArrayInputStream(Charset.forName(encoding).encode(passwd).array());
byte[] buffer = new byte[NCHARS];
int byteCount;
while ((byteCount = in.read(buffer)) > 0) {
digester.update(buffer, 0, byteCount);
}
keyBytes = digester.digest();
}
catch(Exception e){
status = "Error in key generation: " + e.toString();
}
// Initilizing the crypto engine
try {
cipher = Cipher.getInstance(algorithm);
}
catch(Exception e){
status = "Error in intialization: " + e.toString();
}
secretKeySpec = new SecretKeySpec(keyBytes, "AES");
ivParameterSpec = new IvParameterSpec(keyBytes);
}
And two that work
// Getting status
public static String getStatus(){return status;}
public static String getFilename() {
Log.i("[QCOLOCRYPT]","Getting the file name");
return "The Filename is: " + fileName;
}
The non-working function is not being called because its debug message is NOT being printed, while I get the log message AND the return values of the other two. Logcat does not seem to show any errors, so I'm at a loss. Am I calling it wrong?
Ok, so this isn't exactly an answer. It's more of a workaround, I got the function to work, but the only way I could do it is by returning a String. I've tried with an Integer using (Arguments)I; as the signature but I had the same problem. I modified the Java function to return a status string, changed the signature to reflect that, and everything worked perfectly. Though its weird.
I'm trying to change a working example from C sharp to Java but i'm struggling and don't know where the problem is. I contacted Kraken and they advised me that I have the wrong signature... The response is:
{"error":["EAPI:Invalid signature"]}
Here's the C sharp version:
private JsonObject QueryPrivate(string a_sMethod, string props = null)
{
// generate a 64 bit nonce using a timestamp at tick resolution
Int64 nonce = DateTime.Now.Ticks;
props = "nonce=" + nonce + props;
string path = string.Format("/{0}/private/{1}", _version, a_sMethod);
string address = _url + path;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(address);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
webRequest.Headers.Add("API-Key", _key);
byte[] base64DecodedSecred = Convert.FromBase64String(_secret);
var np = nonce + Convert.ToChar(0) + props;
var pathBytes = Encoding.UTF8.GetBytes(path);
var hash256Bytes = sha256_hash(np);
var z = new byte[pathBytes.Count() + hash256Bytes.Count()];
pathBytes.CopyTo(z, 0);
hash256Bytes.CopyTo(z, pathBytes.Count());
var signature = getHash(base64DecodedSecred, z);
webRequest.Headers.Add("API-Sign", Convert.ToBase64String(signature));
if (props != null)
{
using (var writer = new StreamWriter(webRequest.GetRequestStream()))
{
writer.Write(props);
}
}
//Make the request
try
{
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream str = webResponse.GetResponseStream())
{
using (StreamReader sr = new StreamReader(str))
{
return (JsonObject)JsonConvert.Import(sr);
}
}
}
}
}
The full code is here at:
https://bitbucket.org/arrivets/krakenapi/src/cff138b017c38efde2db1a080fb765790a6d04c8/KrakenClient/KrakenClient.cs?at=master&fileviewer=file-view-default
Here is my Java version:
private void fetch() throws UnsupportedEncodingException, IOException, NoSuchAlgorithmException {
String version = "0";
String key = ".....6";
String secret = "....g==";
long nonce = System.currentTimeMillis();
String props = null;
props = "nonce=" + nonce + props; // I've tried this with and without the 'null' on the end
// url
String url = "https://api.kraken.com";
String path = "/" + version + "/private/" + "Balance";
String address = url + path;
// post req
HttpPost httpPost = new HttpPost(address);
// headers
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.setHeader("API-Key", key);
// decode buffer
BASE64Decoder decoder = new BASE64Decoder();
byte[] base64DecodedSecred = decoder.decodeBuffer(secret);
// nonce & props
String np = nonce + (char) 0 + props;
// create byte array
byte[] pathBytes = path.getBytes("UTF-8");
byte[] hash256Bytes = sha256(np);
byte[] z = new byte[pathBytes.length + hash256Bytes.length];
System.arraycopy(pathBytes, 0, z, 0, pathBytes.length);
System.arraycopy(hash256Bytes, 0, z, pathBytes.length, hash256Bytes.length);
// encrypt signature
byte[] signature = hmacEncrypt(z, base64DecodedSecred); // my hmacEncrypt is message, secret (opposite to the c sharp)
BASE64Encoder encoder = new BASE64Encoder();
httpPost.setHeader("API-Sign", encoder.encode(signature));
// Post
List<NameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("nonce", String.valueOf(nonce)));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
// Client & Response
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
// parse
JsonParser jp = new JsonParser();
JsonElement root = jp.parse(EntityUtils.toString(entity));
System.out.println(root); // {"error":["EAPI:Invalid signature"]}
// close client
httpClient.close();
}
I'm sorry to have posted a large bits of code, any help would be appreciated. Thank you!
there is no cchmac 512 encryption in your code. that is why you get this EAPI:Invalid signature"
I have this jersey webResource code:
#Override
public int Foo(long uId, String secretKey, long tileId) {
int answer = 0;
String ans;
try {
ClientResponse response = webResource
// .path("multi-get")
.queryParam("reqtype", "tileBatch")
.queryParam("protocol", "1")
.queryParam("sessionid", String.valueOf(uId))
.queryParam("cookie", String.valueOf(secretKey))
.queryParam("num", "1")
.queryParam("t0", String.valueOf(tileId))
.queryParam("v0", "0")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
String output = response.getEntity(String.class);
answer = response.getEntityInputStream().available();
byte[] byteArray = output.getBytes("UTF-8");
ans = new String(byteArray, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return answer;
}
}
I see String output = response.getEntity(String.class); is not empty and yet in answer = response.getEntityInputStream().available(); then answer == 0 how come?
If I want to parse the 2 first bytes from binary data into an integer
how can I do this? (int) byteArray[0] ?
e.g. 00000000-00010000
Edit
I tried this code:
InputStream entityInputStream = response.getEntityInputStream();
answer = entityInputStream.available();
String output = response.getEntity(String.class);
byte[] byteArray = new byte[2];
// entityInputStream.reset();
entityInputStream.read(byteArray);
String s = new String(byteArray);
but yet byteArray == {0,0} even though output is not empty.
output == ....
�*WZDF04x��:w|������6[�!�M���#HH �� �����TQ�W�""$#�Z $(���ұ=��[��� ��d�s�n6K�������{�99��{����$qE48"
is my way correct?
I see String output = response.getEntity(String.class); is not empty and yet in answer = response.getEntityInputStream().available(); then answer == 0 how come?
When you do response.readEntity(String.class), the input stream is being read from, and clears out the input stream. So your next attempt to retrieve the input stream will return an empty stream.
If I want to parse the 2 first bytes from binary data into an integer how can I do this?
You can simply wrap the InputStream in an DataInputStream, and use DataInputStream.readInt(). Then you can read the rest of the intput stream, with response.readEntity(String.class);. You seem to be trying to read the string, and then the int, which doesn't go with the above statement of yours.
Test
#Path("/string")
public class StringResource {
#GET
public StreamingOutput getString() {
return new StreamingOutput(){
#Override
public void write(OutputStream out)
throws IOException, WebApplicationException {
DataOutputStream outStream = new DataOutputStream(out);
outStream.writeInt(1234567);
outStream.writeUTF("Hello World");
}
};
}
}
#Test
public void testMyResource() throws Exception {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource wr = client
.resource("http://localhost:8080/api/string");
ClientResponse response = wr.get(ClientResponse.class);
InputStream is = response.getEntityInputStream();
DataInputStream dis = new DataInputStream(is);
int num = dis.readInt();
System.out.println(num);
System.out.println(response.getEntity(String.class));
response.close();
}
Prints out 1234567 then Hello World