Я работаю над FatSecretAPI и пытаюсь получить список рецептов.
для доступа к нему необходимо отправить несколько параметров:
oauth_consumer_key String --Your API key when you registered as a developer
oauth_signature_method String-- The method used to generate the signature (only HMAC-SHA1 is supported)
oauth_timestamp Int-- The date and time, expressed in the number of seconds since January 1, 1970 00:00:00 GMT. The timestamp value must be a positive integer and must be equal or greater than the timestamp used in previous requests
oauth_nonce String --A randomly generated string for a request that can be combined with the timestamp to produce a unique value
oauth_version String-- MUST be "1.0"
oauth_signature String-- The signature, a consistent reproducible concatenation of the request elements into a single string. The string is used as an input in hashing or signing algorithms.
method String --MUST be "recipes.search"
И в ответ я получу следующее:
recipe_id – the unique recipe identifier.
recipe_name – the name of the recipe.
recipe_url – URL of this recipe item on www.fatsecret.com.
recipe_description – A short description of the recipe.
recipe_image – URL of this recipe item's default image, only if this is available
У меня есть ответ json, подобный этому:
{
"recipes":{
"recipe":{
"recipe_description":"Healthy fish with a tasty sauce.",
"recipe_id":"91",
"recipe_image":"http:\/\/www.fatsecret.com\/static\/recipe\/bf0c5912-9cf8-4e7a-b07a-6703c4b77082.jpg",
"recipe_name":"Baked Lemon Snapper",
"recipe_url":"http:\/\/www.fatsecret.com\/recipes\/baked-lemon-snapper\/Default.aspx"
}
}
}
И мой Apicall выглядит так:
открытый интерфейс MyCallApi {
String BASE_URL = "http://platform.fatsecret.com/";
@POST("rest/server.api/")
Call<Recipes> getRecipes(@Query("oauth_consumer_key") String oauth_consumer_key,
@Query("oauth_signature_method") String oauth_signature_method,
@Query("oauth_timestamp") int oauth_timestamp,
@Query("oauth_nonce") String oauth_nonce,
@Query("oauth_version") String oauth_version,
@Query("oauth_signature") String oauth_signature,
@Query("method") String method);
И мой класс POJO для рецептов выглядит так:
public class Recipes {
@SerializedName("recipe")
@Expose
private Recipe recipe;
public Recipe getRecipe() {
return recipe;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
}
@NonNull
@Override
public String toString() {
return "ClassPojo [recipe = " + recipe + "]";
}
}
А для данных внутри объекта рецептов:
public class Recipe {
@SerializedName("recipe_name")
@Expose
private String recipe_name;
@SerializedName("recipe_url")
@Expose
private String recipe_url;
@SerializedName("recipe_description")
@Expose
private String recipe_description;
@SerializedName("recipe_image")
@Expose
private String recipe_image;
@SerializedName("recipe_id")
@Expose
private String recipe_id;
public String getRecipe_name() {
return recipe_name;
}
public void setRecipe_name(String recipe_name) {
this.recipe_name = recipe_name;
}
public String getRecipe_url() {
return recipe_url;
}
public void setRecipe_url(String recipe_url) {
this.recipe_url = recipe_url;
}
public String getRecipe_description() {
return recipe_description;
}
public void setRecipe_description(String recipe_description) {
this.recipe_description = recipe_description;
}
public String getRecipe_image() {
return recipe_image;
}
public void setRecipe_image(String recipe_image) {
this.recipe_image = recipe_image;
}
public String getRecipe_id() {
return recipe_id;
}
public void setRecipe_id(String recipe_id) {
this.recipe_id = recipe_id;
}
@NonNull
@Override
public String toString() {
return "ClassPojo [recipe_name = " + recipe_name + "," +
" recipe_url = " + recipe_url + ", " +
"recipe_description = " + recipe_description + "," +
" recipe_image = " + recipe_image + "," +
" recipe_id = " + recipe_id + "]";
}
}
Реализация модификаций:
public class RecipeActivity extends AppCompatActivity {
final static private String APP_METHOD = "GET";
final static private String APP_KEY = "here api key";
final static private String APP_SECRET = "ssecret key";
final static private String APP_URL = "http://platform.fatsecret.com/rest/server.api";
private static final String HMAC_SHA1_ALGORITHM = "HMAC-SHA1";
private static String paramify(String[] params) {
String[] p = Arrays.copyOf(params, params.length);
Arrays.sort(p);
return join(p, "&");
}
private static String join(String[] array, String separator) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i > 0)
b.append(separator);
b.append(array[i]);
}
return b.toString();
}
private static String nonce() {
Random r = new Random();
StringBuilder n = new StringBuilder();
for (int i = 0; i < r.nextInt(8) + 2; i++)
n.append(r.nextInt(26) + 'a');
return n.toString();
}
Long tsLong = System.currentTimeMillis() / 1000;
int ts = Integer.parseInt(tsLong.toString());
private static String[] generateOauthParams() {
return new String[]{
"oauth_consumer_key=" + APP_KEY,
"oauth_signature_method=HMAC-SHA1",
"oauth_timestamp=" +
Long.valueOf(System.currentTimeMillis() * 2).toString(),
"oauth_nonce=" + nonce(),
"oauth_version=1.0",
"format=json"};
}
private static String signature(String[] params) {
String[] p = {RecipeActivity.APP_METHOD, Uri.encode(RecipeActivity.APP_URL), Uri.encode(paramify(params))};
String s = join(p, "&");
SecretKey sk = new SecretKeySpec(APP_SECRET.getBytes(), HMAC_SHA1_ALGORITHM);
try {
Mac m = Mac.getInstance(HMAC_SHA1_ALGORITHM);
m.init(sk);
return Uri.encode(new String(Base64.encode(m.doFinal(s.getBytes()), Base64.DEFAULT)).trim());
} catch (java.security.NoSuchAlgorithmException | java.security.InvalidKeyException e) {
Log.w("FatSecret_TEST FAIL", e.getMessage());
return null;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe);
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(MyCallApi.BASE_URL)
.build();
MyCallApi myCallApi = retrofit.create(MyCallApi.class);
Call<Recipes> call = myCallApi.getRecipes("c30f50a1c5474070b4db11a506d99666",
"HMAC-SHA1", ts
, nonce()
, "1.0", signature(generateOauthParams()),
"recipes.search");
call.enqueue(new Callback<Recipes>() {
@Override
public void onResponse(@NonNull Call<Recipes> call, @NonNull Response<Recipes> response) {
Log.i("if works", response.toString());
}
@Override
public void onFailure(@NonNull Call<Recipes> call, @NonNull Throwable t) {
Log.i("if not", t.getMessage());
}
});
}
}
Но я получаю наиболее часто задаваемую ошибку.И я не могу решить ее самостоятельно. Я новичок в модернизации.Я не знаю, что и где я делаю неправильно, пожалуйста, проверьте реализации и направьте меня, чтобы получить ответ успешно *.Помните, что я должен отправить эти параметры вместе с запросом на модернизацию. *