我正在为食谱应用程序项目使用Spoonacular API。尝试向API发出多个GET请求时会出现问题。第一个请求是带有查询参数的简单搜索。第一个请求的结果JSON包含一个Recipe ID,我使用该ID发出第二个GET请求,出现问题。API仅在我第一次发出请求时响应,但之后它会以错误代码500[内部服务器错误]响应。
我已经在Postman上测试了GET请求,但每次都运行良好。我是使用API的新手,任何帮助都将不胜感激。
这是我的改装服务班
公共类ServiceGenerator{
public static final String API_BASE_URL = "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass, final String HostName, final String KeyVal)
{
if (!TextUtils.isEmpty(HostName) && !TextUtils.isEmpty(KeyVal))
{
HeadersInterceptor interceptor = new HeadersInterceptor(HostName,KeyVal);
if (!httpClient.interceptors().contains(interceptor))
{
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
这是我用来添加请求头的拦截器。
公共类HeaderInterceptor实现拦截器{
private String HostName,KeyVal;
HeadersInterceptor(final String HostName,final String KeyVal) {
this.HostName = HostName;
this.KeyVal = KeyVal;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("X-RapidAPI-Host",HostName)
.addHeader("X-RapidAPI-Key",KeyVal);
Request request = builder.build();
return chain.proceed(request);
}
}
这是我的片段,它进行搜索查询并成功返回结果[Receipe ID's]
公共类ListSelectedFragments扩展了片段{
private ProgressBar PreviewFragPrg;
private final String TAG = "ListSelectedFragment->";
private PreviewRecipeAdapter adapter;
private RecyclerView SelectedItemRV;
private ArrayList<RecipePreviewHolder> RecipePreviewsList = new ArrayList<>();
public ListSelectedFragments() {
// Required empty public constructor
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_list_selected_fragments, container, false);
SelectedItemRV = view.findViewById(R.id.SelectedItemRV);
TextView DisplayNameTV = view.findViewById(R.id.DisplayNameTV);
PreviewFragPrg = view.findViewById(R.id.PreviewFragPrg);
ImageView BackBtn = view.findViewById(R.id.BackBtn);
BackBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getFragmentManager() != null) {
getFragmentManager().popBackStackImmediate();
}
}
});
if (getArguments() != null) {
final String QueryTag = getArguments().getString("QueryTag");
final String CuisineName = getArguments().getString("CuisineName");
if(CuisineName!=null){
DisplayNameTV.setText(CuisineName);
}
if(QueryTag!=null){
ProcessQuery(QueryTag);
}
}
return view;
}
private void ProcessQuery(final String QueryStr){
String hostname = getResources().getString(R.string.spoonacular_host_name);
String key = getResources().getString(R.string.spoonacular_apikey_val);
final ServiceGenerator.GetDataService mService =
ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);
Call<RecipeInfoModel> call = mService.getRecipes(QueryStr);
call.enqueue(new Callback<RecipeInfoModel>() {
@Override
public void onResponse(@NonNull Call<RecipeInfoModel> call,
@NonNull Response<RecipeInfoModel> response)
{
Log.d(TAG, "Request Response Received");
Log.d(TAG, response.toString());
if (response.body() != null) {
Results[] mRES = response.body().getResults();
SetUpRecipePreviews(mRES);
PreviewFragPrg.setVisibility(View.GONE);
}
}
@Override
public void onFailure(@NonNull Call<RecipeInfoModel> call, @NonNull Throwable t) {
Log.d(TAG, "Request Failed");
Log.d(TAG, call.toString());
Log.d(TAG, "Throwable ->" + t);
PreviewFragPrg.setVisibility(View.GONE);
Toast.makeText(getActivity(),"Could not get required recipes",Toast.LENGTH_SHORT).show();
}
});
Log.d(TAG, "User Inputed Request\n"+call.request().url().toString());
}
private void SetUpRecipePreviews(final Results[] mRES) {
RecipePreviewsList.clear();
adapter = new PreviewRecipeAdapter(getActivity(),RecipePreviewsList);
SelectedItemRV.setLayoutManager(new GridLayoutManager(getActivity(), 2));
SelectedItemRV.setAdapter(adapter);
for (Results mRE : mRES) {
String ImgUrls = mRE.getImage();
RecipePreviewHolder obj = new RecipePreviewHolder(Integer.valueOf(mRE.getId()),
mRE.getTitle(), ImgUrls);
Log.d("GlideLogs->","Rid->"+mRE.getId());
Log.d("GlideLogs->","Img URL->"+ ImgUrls);
Log.d("GlideLogs->","Name->"+mRE.getTitle());
RecipePreviewsList.add(obj);
}
if(RecipePreviewsList.size()>1){
adapter.notifyDataSetChanged();
}
}
这是我在点击食谱卡后从片段转换到的活动…在附加中发送食谱ID。此函数在收到intent extras后立即调用。
私有void RetrieveRecipeInfo(final int recipeID){
String hostname = getResources().getString(R.string.spoonacular_host_name);
String key = getResources().getString(R.string.spoonacular_apikey_val);
final ServiceGenerator.GetDataService mService =
ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);
Call<RecipeDetailedInfo> call = mService.getInformation(185071);
Log.d(TAG , "Your GET Request:\n"+call.request().url().toString());
call.enqueue(new Callback<RecipeDetailedInfo>() {
@Override
public void onResponse(@NonNull Call<RecipeDetailedInfo> call, @NonNull Response<RecipeDetailedInfo> response)
{
Log.d(TAG,"OnResponse() Called\n");
Log.d(TAG,"Response = "+ response);
if(response.body()!=null) {
String obj = response.body().getSourceUrl();
Log.d(TAG,"Getting Recipe Info\n");
Log.d(TAG, String.valueOf(obj));
}
}
@Override
public void onFailure(@NonNull Call<RecipeDetailedInfo> call, @NonNull Throwable t){
}
});
}
使用postman,我每次都会得到结果,但在我的应用程序中,API在第一个请求后停止响应。我包含标题的方式有问题吗?
所以我终于把事情做好了。问题出在HeaderInterceptor.java上。我曾使用拦截器在调用中添加标题,但我找到了一种更简单的方法,效果很好。
只需添加@Header,并调用添加头,而无需在改造中使用拦截器。
public interface GetDataService {
@GET("recipes/complexSearch?")
Call<RecipeInfoModel> getRecipes(
@Header("X-RapidAPI-Host") String api,
@Header("X-RapidAPI-Key") String apiKey,
@Query("query") String query_str);
}
我无法运行服务器......我得到的错误为 如何解决这个错误! 当我尝试使用不同的端口时....所有的人都给了我同样的错误!
代码如果出现错误,编辑器会在右边栏高亮显示红色的条标,如果有多处错误就会显示多个条标. 如果想快捷查看错误代码,可以通过点击右边栏的条标进行快速跳转。 跳转到下一个错误位置 操作步骤: 菜单栏: Navigate —> Next Highlighted Error 快捷键: Mac: Fn + F2 Windows\/Linux: F2 跳转到上一个错误位置 操作步骤: 菜单栏: Navigate
还有其他的建议吗?
问题内容: 我正在尝试使用NSLocalizedString本地化我的应用程序。当我导入XLIFF文件时,大多数工作都像一个超级按钮,但是有些却没有,有些字符串没有本地化。我注意到问题出在NSLocalizedString中,其中包含一些变量,例如: 要么 也许这不是这类东西的正确语法。有人可以向我解释如何迅速做到这一点?非常感谢你。 问题答案: 您可以在中使用format参数,因此您的示例如下所
问题内容: 我试图按照此链接中的建议将错误返回到对控制器的调用,以便客户端可以采取适当的措施。javascript通过jqueryAJAX调用控制器。仅在不将状态设置为error的情况下,我才可以重新获得Json对象。这是示例代码 如果没有设置状态码,我会得到Json。如果设置状态代码,则会返回状态代码,但不会返回Json错误对象。 更新 我想将Error对象作为JSON发送,以便可以处理ajax
据我所知,直线的意思是,那个变量运动得到乘以向量inputVec的x部分的绝对值,但我不明白接下来会发生什么。