I'm working with the Bitfinex API and the version of the API is 1.
But I have a problem that can not be solved.
When I use '/v1/order/new', the server sends to the message "Key symbol was not present."
I can not find which point is the problem.
The parameter settings are as belows.
Please advise.
========== ========== ========== ==========
/**
Create Header, Param
*/
JSONObject json = new JSONObject();
json.put("request", targetURL);
json.put("nonce", Long.toString(getNonce()));
String payload = json.toString();
String payload_base64 = Base64.getEncoder().encodeToString(payload.getBytes());
String payload_sha384hmac = hmacDigest(payload_base64, apiKeySecret, ALGORITHM_HMACSHA384);
HttpTask http = new HttpTask(URL, Method.POST);
http.addHeader("X-BFX-APIKEY", apiKey);
http.addHeader("X-BFX-PAYLOAD", payload_base64);
http.addHeader("X-BFX-SIGNATURE", payload_sha384hmac);
http.setContentType("x-www-urlencoded");
http.setAcceptType("application/xml");
http.addParam("symbol", "btcusd");
http.addParam("amount", "0.01");
http.addParam("price", "0.01");
http.addParam("side", "buy");
http.addParam("type", "exchange market");
http.addParam("is_hidden", "false");
http.addParam("is_postonly", "true");
http.addParam("use_all_available", "0");
http.addParam("exchange", "bitfinex");
http.addParam("ocoorder", "false");
http.addParam("buy_price_oco", "0");
/**
Parsing Param
*/
StringBuilder sb = new StringBuilder();
Set<String> key = m_params.keySet();
int totalCount = key.size();
if (totalCount > 0) {
int index = 0;
for (Iterator<String> iterator = key.iterator(); iterator.hasNext();) {
String keyValue = (String) iterator.next();
String valueValue = (String) m_params.get(keyValue);
sb.append(String.format("%s=%s", keyValue, valueValue));
if (index < totalCount - 1) {
sb.append("&");
}
index++;
}
query = sb.toString();
}
/**
send Param
*/
if (!query.isEmpty()) {
DataOutputStream wr;
try {
wr = new DataOutputStream(m_connection.getOutputStream());
wr.writeBytes(query);
wr.flush();
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
You need to put all params in payload object.
Here is my example on JAVASCRIPT:
auth_v1_request(path, params){
return new Promise((resolve, reject) => {
// console.log(this.account);
const apiKey = this.account.api_key;
const apiSecret = this.account.api_secret;
const apiPath = '/' + path;
const nonce = (Date.now() * 1000).toString();
const completeURL = `${ CONFIG.BITFINEX.API_URL }${apiPath}`;
params.nonce = nonce;
params.request = apiPath;
const payload = new Buffer(JSON.stringify(params))
.toString('base64');
const signature = crypto
.createHmac('sha384', apiSecret)
.update(payload)
.digest('hex');
const options = {
url: completeURL,
headers: {
'X-BFX-APIKEY': apiKey,
'X-BFX-PAYLOAD': payload,
'X-BFX-SIGNATURE': signature
},
body: JSON.stringify(params),
json: true
};
request.post(options, (error, response, res_body) => {
console.log(error);
console.log(res_body);
if(error) {
reject(error);
}
else {
let parsed;
try {
parsed = res_body;
if(parsed.message){
reject(parsed);
}
else {
resolve(parsed);
}
}
catch(err) {
reject(err);
}
}
})
});
}
Related
I am unable to do this in my android app using java language. I am using the retrofit library for this but the problem is the signature. unable to generate proper signature which gives me an error. It is working in POSTMAN and getting proper responses. Help me to convert this in JAVA.
Documentation of API - https://docs.wazirx.com/#fund-details-user_data
POSTMAN PRE-REQUEST SCRIPT
MAIN PARAMS --> BASE_URL, API_KEY, SECRET_KEY, SIGNATURE & TIMESTAMP in miliseconds.
var navigator = {}; //fake a navigator object for the lib
var window = {}; //fake a window object for the lib
const privateKey = pm.environment.get("rsa_private_key");
const secretKey = pm.environment.get("secret_key");
// Set Current Time
var time = new Date().getTime()
postman.setEnvironmentVariable("current_time", time)
query_a = pm.request.url.query.toObject(true)
// Generate Request Payload
let query_string_array = []
Object.keys(query_a).forEach(function(key) {
if (key == 'signature') { return }
if (key == 'timestamp') {
query_string_array.push(key + "=" + time)
}
else if (typeof query_a[key] == "string") {
query_string_array.push(key + "=" + query_a[key])
} else {
query_a[key].forEach(function(value){
query_string_array.push(key + "=" + value)
})
}
})
const payload = query_string_array.join("&")
console.log("Request Payload = ", payload)
if(secretKey) {
const signature = CryptoJS.HmacSHA256(payload, secretKey) + ''
pm.environment.set("signature", signature)
console.log("Signature = "+signature);
} else {
// Download RSA Library
pm.sendRequest(pm.environment.get("rsa_library_js"), function (err, res) {
if (err){
console.log("Error: " + err);
}
else {
// Compile & Run RSA Library
eval(res.text())();
// Sign Payload
var signatureLib = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
signatureLib.init(privateKey);
signatureLib.updateString(payload);
var signatureHash = hex2b64(signatureLib.sign());
console.log("Signature = ", signatureHash)
// Assign Values
pm.environment.set("signature", encodeURIComponent(signatureHash, "UTF-8"))
}
})
}
Java Code:
//REQUEST CLASS START -->
public class Request {
String baseUrl;
String apiKey="1***uR7";
String apiSecret="b1**qVmh";
Signature sign = new Signature();
public Request(String baseUrl, String apiKey, String apiSecret) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
this.apiSecret = apiSecret;
}
private void printResponse(HttpURLConnection con) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
private void printError(HttpURLConnection con) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
private String getTimeStamp() {
long timestamp = System.currentTimeMillis();
return "timestamp=" + timestamp;
}
//concatenate query parameters
private String joinQueryParameters(HashMap<String,String> parameters) {
String urlPath = "";
boolean isFirst = true;
for (Map.Entry mapElement : parameters.entrySet()) {
if (isFirst) {
isFirst = false;
urlPath += mapElement.getKey() + "=" + mapElement.getValue();
} else {
urlPath += "&" + mapElement.getKey() + "=" + mapElement.getValue();
}
}
return urlPath;
}
private void send(URL obj, String httpMethod) throws Exception {
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
if (httpMethod != null) {
con.setRequestMethod(httpMethod);
}
//add API_KEY to header content
con.setRequestProperty("X-API-KEY", apiKey);
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // success
printResponse(con);
} else {
printError(con);
}
}
public void sendPublicRequest(HashMap<String,String> parameters, String urlPath) throws Exception {
String queryPath = joinQueryParameters(parameters);
URL obj = new URL(baseUrl + urlPath + "?" + queryPath);
System.out.println("url:" + obj.toString());
send(obj, null);
}
public void sendSignedRequest(HashMap<String,String> parameters, String urlPath, String httpMethod) throws Exception {
String queryPath = "";
String signature = "";
if (!parameters.isEmpty()) {
queryPath += joinQueryParameters(parameters) + "&" + getTimeStamp();
} else {
queryPath += getTimeStamp();
}
try {
signature = sign.getSignature(queryPath, apiSecret);
}
catch (Exception e) {
System.out.println("Please Ensure Your Secret Key Is Set Up Correctly! " + e);
System.exit(0);
}
queryPath += "&signature=" + signature;
URL obj = new URL(baseUrl + urlPath + "?" + queryPath);
System.out.println("url:" + obj.toString());
send(obj, httpMethod);
}
}
//REQUEST CLASS END -->
//SPOT CLASS START -->
public class Spot {
private static final String API_KEY = System.getenv("1***57");
private static final String API_SECRET = System.getenv("b****n8");
HashMap<String,String> parameters = new HashMap<String,String>();
Request httpRequest;
public Spot() {
String baseUrl = "https://api.wazirx.com";
httpRequest = new Request(baseUrl, API_KEY, API_SECRET);
}
public void account() throws Exception {
httpRequest.sendSignedRequest(parameters, "/sapi/v1/funds", "GET");
}
}
//SPOT CLASS END-->
//SIGNATURE CLASS START-->
public class Signature {
final String HMAC_SHA256 = "HmacSHA256";
//convert byte array to hex string
private String bytesToHex(byte[] bytes) {
final char[] hexArray = "0123456789abcdef".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0, v; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public String getSignature(String data, String key) {
byte[] hmacSha256 = null;
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA256);
Mac mac = Mac.getInstance(HMAC_SHA256);
mac.init(secretKeySpec);
hmacSha256 = mac.doFinal(data.getBytes());
} catch (Exception e) {
throw new RuntimeException("Failed to calculate hmac-sha256", e);
}
return bytesToHex(hmacSha256);
}
}
//SIGNATURE CLASS END-->
I am new to the HTTP request in java. I have been trying to send an HTTP Post request to my NODE.JS server with the parameter key:12345. However, it doesn't send anything to my server. I tried tested my NOEDJS server to see if it worked in POSTMAN, and it did. So I am sure that this is something with the java that I made. I think a look at my code would help. Here it is down below.
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class ConnectionFactory {
private double API_VERSION = 0;
private String API = "";
private String METHOD = "POST";
private String USER_AGENT = "Mozilla/5.0";
private String TYPE = "application/x-www-form-urlencoded";
private String data = "";
private URL connection;
private HttpURLConnection finalConnection;
private HashMap<String, String> fields = new HashMap<String, String>();
public ConnectionFactory(String[] endpoint, String url, double version) {
this.API_VERSION = version;
this.API = url;
fields.put("version", String.valueOf(version));
for (int i = 0; i < endpoint.length; i++) {
String[] points = endpoint[i].split(";");
for (int f = 0; f < points.length; f++) {
fields.put(points[f].split(":")[0], points[f].split(":")[1]);
}
}
}
public String buildConnection() {
StringBuilder content = new StringBuilder();
if (!this.getEndpoints().equalsIgnoreCase("") && !this.getEndpoints().isEmpty()) {
String vars = "";
String vals = "";
try {
for (Map.Entry<String, String> entry: fields.entrySet()) {
vars = entry.getKey();
vals = entry.getValue();
data += ("&" + vars + "=" + vals);
}
if (data.startsWith("&")) {
data = data.replaceFirst("&", "");
}
connection = new URL(API);
BufferedReader reader = new BufferedReader(new InputStreamReader(readWithAccess(connection, data)));
String line;
while ((line = reader.readLine()) != null) {
content.append(line + "\n");
}
reader.close();
return content.toString();
} catch (Exception e) {
System.err.println(e.getMessage());
}
} else {
return null;
}
return null;
}
private InputStream readWithAccess(URL url, String data) {
try {
byte[] out = data.toString().getBytes();
finalConnection = (HttpURLConnection) url.openConnection();
finalConnection.setRequestMethod(METHOD);
finalConnection.setDoOutput(true);
finalConnection.addRequestProperty("User-Agent", USER_AGENT);
finalConnection.addRequestProperty("Content-Type", TYPE);
finalConnection.connect();
try {
OutputStream os = finalConnection.getOutputStream();
os.write(out);
} catch (Exception e) {
System.err.println(e.getMessage());
}
return finalConnection.getInputStream();
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
}
}
public String getApiVersion() {
return String.valueOf(API_VERSION);
}
public String getEndpoints() {
return fields.toString();
}
public String getEndpointValue(String key) {
return fields.get(key);
}
public void setUserAgent(String userAgent) {
this.USER_AGENT = userAgent;
}
public void setMethod(String method) {
this.METHOD = method;
}
public void setSubmissionType(String type) {
this.TYPE = type;
}
}
public class example {
public static void main(String[] args) {
double version = 0.1;
String url = "http://localhost:3000";
String[] fields = {
"key:12345"
};
ConnectionFactory connection = new ConnectionFactory(fields, url, version);
connection.setUserAgent("Mozilla/5.0");
String response = connection.buildConnection();
System.out.println(response);
}
}
Here is the code for my node.js server
var http = require('http');
var url = require('url');
var queryString = require('querystring')
var StringDecoder = require('string_decoder').StringDecoder;
var server = http.createServer(function(req, res) {
//parse the URL
var parsedURL = url.parse(req.url, true);
//get the path
var path = parsedURL.pathname;
var trimmedPath = path.replace(/^\/+|\/+$/g, '');
//queryString
var queryStringObject = parsedURL.query;
console.log(queryStringObject);
if (queryStringObject.key == 12345) {
console.log("true")
res.end("true")
} else {
console.log("failed")
res.end("false")
}
// var query = queryStringObject.split()
});
server.listen(3000, function() {
console.log("Listening on port 3000");
});
The is no problem with your java client
The problem is that you are sending the content of your POST request as ""application/x-www-form-urlencoded" and then in your nodeJS server you are reading it as a query string
Here is a correct example using ExpressJS :
const express = require('express')
const app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/test', function(req, res) {
var key = req.body.key;
if (key==12345)
res.send(true );
else
res.send(false);
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
I'm making an android version of my c# program and I need to convert this method to java considering that apache client was deprecated and I'm a newbie
I'm using this method in c# to connect with a php file on my site using POST method to pass it user name and password then return result using echo
my C# code is
protected string serverUrl = "http://soft.daiilydeal.com/soft.php";
public static string UserName = "user";
public static string Password = "password";
private void frmRegister_Shown(object sender, EventArgs e)
{
string response;
new Thread(delegate(object t)
{
response = this.Submit(new string[] { "action", "login", "username", UserName, "password", Password });
if (response == "allowed")
{
return;
}
else
{
this.Invoke(new MethodInvoker(delegate()
{
this.Close();
}));
var action = MessageBox.Show("This copy of the software is not illegal", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}) { IsBackground = true }.Start();
}
and this is the most important method
private string Submit(string[] parameters)
{
ServicePointManager.Expect100Continue = false;
string arg_0B_0 = string.Empty;
string result;
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(this.serverUrl);
httpWebRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = false;
httpWebRequest.Credentials = CredentialCache.DefaultCredentials;
httpWebRequest.Timeout = 30000;
byte[] array = new byte[0];
string text = string.Empty;
for (int i = 0; i < parameters.Length; i += 2)
{
text += string.Format("{0}={1}&", parameters[i], HttpUtility.UrlEncode(parameters[i + 1]));
}
httpWebRequest.ContentLength = (long)text.Length;
array = Encoding.UTF8.GetBytes(text);
Stream requestStream = httpWebRequest.GetRequestStream();
requestStream.Write(array, 0, array.Length);
requestStream.Close();
WebResponse response = httpWebRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
string text2 = streamReader.ReadToEnd();
response.Close();
result = text2;
}
catch (Exception ex)
{
result = "Error: " + ex.Message;
}
return result;
}
I searched but most answers use apache client and HttpURLConnction
I want to get google contacts in my Blackberry Application. Is there any public libraries availabile for blackberry to do this?
I try to use Oauth-SignPost. But the libraies used in it not supported by blackberry.Then I try the following code
public static String requestToken(){
String url = C.REQUEST_URL;
String header = oauth_header(url, HttpProtocolConstants.HTTP_METHOD_GET);
String requestTokenUrl = concatURL(url, header);
HttpConnection httpConn = null;
InputStream input = null;
try{
HttpConnectionFactory factory = new HttpConnectionFactory( requestTokenUrl,
HttpConnectionFactory.TRANSPORT_WIFI |
HttpConnectionFactory.TRANSPORT_WAP2 |
HttpConnectionFactory.TRANSPORT_BIS |
HttpConnectionFactory.TRANSPORT_BES |
HttpConnectionFactory.TRANSPORT_DIRECT_TCP);
httpConn = factory.getNextConnection();
httpConn.setRequestMethod(HttpProtocolConstants.HTTP_METHOD_GET);
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
input = httpConn.openDataInputStream();
int resp = httpConn.getResponseCode();
if (resp == HttpConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
int ch;
while ( (ch = input.read()) != -1){
buffer.append( (char) ch);
}
String content = buffer.toString();
System.out.println("Response"+content);
}
return "";
} catch (IOException e) {
return "exception";
} catch (NoMoreTransportsException nc) {
return "noConnection";
} finally {
try {
httpConn.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The oauth_header() which create the appending parameters
public static String oauth_header(String url, String method) {
String nonce = nonce();
long timestamp = timestamp();
Hashtable pairs = new Hashtable();
pairs.put(C.OAUTH_CONSUMER_KEY, C.CONSUMER_KEY);
pairs.put(C.OAUTH_NONCE, nonce);
pairs.put(C.OAUTH_SIGNATURE_METHOD, C.SIGNATURE_METHOD);
pairs.put(C.OAUTH_TIMESTAMP, Long.toString(timestamp));
pairs.put(C.OAUTH_SCOPE,C.SCOPE);
pairs.put(C.OAUTH_VERSION, "1.0");
String sig = signature(method, url, pairs);
StringBuffer header_sb = new StringBuffer();
header_sb.append(C.OAUTH_CONSUMER_KEY).append("=").append(C.CONSUMER_KEY).append(",");
header_sb.append(C.OAUTH_NONCE).append("=").append(nonce).append(",");
header_sb.append(C.OAUTH_SIGNATURE).append("=").append(URLUTF8Encoder.encode(sig)).append(",");
header_sb.append(C.OAUTH_SIGNATURE_METHOD).append("=").append(C.SIGNATURE_METHOD).append(",");
header_sb.append(C.OAUTH_TIMESTAMP).append("=").append(Long.toString(timestamp)).append(",");
header_sb.append(C.OAUTH_SCOPE).append("=").append(C.SCOPE);
header_sb.append(C.OAUTH_VERSION).append("=").append("1.0");
return header_sb.toString();
}
Signature() and concatUrl() here
private static String signature(String method, String requestURL, Hashtable pairs) {
StringBuffer sb = new StringBuffer();
String[] keys = new String[pairs.size()];
Enumeration e = pairs.keys();
int i = 0;
while(e.hasMoreElements()) {
String k = (String)e.nextElement();
keys[i++] = k + "=" + URLUTF8Encoder.encode((String)pairs.get(k));
}
Arrays.sort(keys, new Comparator() {
public int compare(Object arg0, Object arg1) {
return ((String)arg0).compareTo((String)arg1);
}
});
for(i = 0; i < keys.length; i++) {
sb.append(keys[i]).append('&');
}
sb.deleteCharAt(sb.length()-1);
String msg = method.toUpperCase() +"&" + URLUTF8Encoder.encode(requestURL) + "&" + URLUTF8Encoder.encode(sb.toString());
System.out.println(msg);
StringBuffer key = new StringBuffer();
if(C.CONSUMER_SECRET != null) key.append(URLUTF8Encoder.encode(C.CONSUMER_SECRET));
key.append('&');
/* if(Const.tokenSecret != null){
key.append(URLUTF8Encoder.encode(Const.tokenSecret));
}*/
try {
return hmacsha1(key.toString(), msg);
} catch (Exception ex) {
return null;
}
}
private static String hmacsha1(String key, String message)
throws CryptoTokenException, CryptoUnsupportedOperationException, IOException {
HMACKey k = new HMACKey(key.getBytes());
HMAC hmac = new HMAC(k, new SHA1Digest());
hmac.update(message.getBytes());
byte[] mac = hmac.getMAC();
return Base64OutputStream.encodeAsString(mac, 0, mac.length, false, false);
}
public static String concatURL(String url, String header){
String newurl=url;
header = header.replace(',', '&');
newurl = newurl+"?"+header;
return newurl;
}
Then I get the signature_invalid Message. please Help me to find out the error.
I am getting the following error:
<error_code>104</error_code>
<error_msg>Incorrect signature</error_msg>
What should I be setting contentType type as? Should I set as:
String contentType = "application/x-www-form-urlencoded";
or
String contentType = "multipart/form-data; boundary=" + kStringBoundary;
This is how I am writing the stream:
HttpURLConnection conn = null;
OutputStream out = null;
InputStream in = null;
try {
conn = (HttpURLConnection) _loadingURL.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
if (method != null) {
conn.setRequestMethod(method);
if ("POST".equals(method)) {
//"application/x-www-form-urlencoded";
String contentType = "multipart/form-data; boundary=" + kStringBoundary;
//String contentType = "application/x-www-form-urlencoded";
conn.setRequestProperty("Content-Type", contentType);
}
// Cookies are used in FBPermissionDialog and FBFeedDialog to
// retrieve logged user
conn.connect();
out = conn.getOutputStream();
if ("POST".equals(method)) {
String body = generatePostBody(postParams);
if (body != null) {
out.write(body.getBytes("UTF-8"));
}
}
in = conn.getInputStream();
Here's the method I am using to publish the stream:
private void publishFeed(String themessage) {
//Intent intent = new Intent(this, FBFeedActivity.class);
// intent.putExtra("userMessagePrompt", themessage);
// intent.putExtra("attachment",
Map<String, String> getParams = new HashMap<String, String>();
// getParams.put("display", "touch");
// getParams.put("callback", "fbconnect://success");
// getParams.put("cancel", "fbconnect://cancel");
Map<String, String> postParams = new HashMap<String, String>();
postParams.put("api_key", _session.getApiKey());
postParams.put("method", "stream.publish");
postParams.put("session_key", _session.getSessionKey());
postParams.put("user_message", "TESTING 123");
// postParams.put("preview", "1");
postParams.put("attachment", "{\"name\":\"Facebook Connect for Android\",\"href\":\"http://code.google.com/p/fbconnect-android/\",\"caption\":\"Caption\",\"description\":\"Description\",\"media\":[{\"type\":\"image\",\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}");
// postParams.put("user_message_prompt", "22222");
try {
loadURL("http://api.facebook.com/restserver.php", "POST", getParams, postParams);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Here is generatePostBody() :
private String generatePostBody(Map<String, String> params) {
StringBuilder body = new StringBuilder();
StringBuilder endLine = new StringBuilder("\r\n--").append(kStringBoundary).append("\r\n");
body.append("--").append(kStringBoundary).append("\r\n");
for (Entry<String, String> entry : params.entrySet()) {
body.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"\r\n\r\n");
String value = entry.getValue();
if ("user_message_prompt".equals(entry.getKey())) {
body.append(value);
}
else {
body.append(CcUtil.encode(value));
}
body.append(endLine);
}
return body.toString();
}
Thanks.
This is from Facebook Developers Wiki: http://wiki.developers.facebook.com/index.php/API
Note: If you manually form your HTTP
POST requests to Facebook, you must
include the request data in the POST
body. In addition, you should include
a Content-Type: header of
application/x-www-form-urlencoded.
Use multipart/form-data when uploading files only (e.g. Photos.upload on Facebook API)
Also, Based on this API reference, http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application, this is what you're doing wrong.
1) Don't use HashMap to store Facebook parameters. Parameters must be sorted by their key. Rather use SortedMap interface and use TreeMap to store Facebook parameters.
2) Always include the sig parameter in the map before sending the call to Facebook. You're getting a "104 Incorrect signature" because Facebook doesn't find the sig parameter in your request.
The reference (http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application) shows exactly how to create a MD5 signature which facebook uses.
Here's how to quickly create a sig value for Facebook.
String hashString = "";
Map<String, String> sortedMap = null;
if (parameters instanceof TreeMap) {
sortedMap = (TreeMap<String, String>) parameters;
} else {
sortedMap = new TreeMap<String, String>(parameters);
}
try {
Iterator<String> iter = sortedMap.keySet().iterator();
StringBuilder sb = new StringBuilder();
synchronized (iter) {
while (iter.hasNext()) {
String key = iter.next();
sb.append(key);
sb.append("=");
String value = sortedMap.get(key);
sb.append(value == null ? "" : value);
}
}
sb.append(secret);
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] digested = digest.digest(sb.toString().getBytes());
BigInteger bigInt = new BigInteger(1, digested);
hashString = bigInt.toString(16);
while (hashString.length() < 32) {
hashString = "0" + hashString;
}
} catch (NoSuchAlgorithmException nsae) {
// TODO: handle exception
logger.error(e.getLocalizedMessage(), e);
}
return hashString;