解析API的HttpResponse为对象

huangapple go评论64阅读模式
英文:

Parsing HttpResponse from API into objects

问题

我正在开发一个食谱应用,目前还处于非常早期的阶段。我以前从未使用过API,但我对它有基本的理解,我已经进行了大量的搜索,但基本上这就是问题的要点:我正在使用来自RapidAPI的食谱API,它可以返回多个响应。我想将所有响应解析成我的Recipe类的对象。我已经让代码工作正常,但我觉得应该有更好的方法来实现我想做的事情。我目前正在使用一个函数将字符串解析成Recipe对象的ArrayList,使用Try Catch块来在达到索引越界异常时终止。

Rapid API发送信息的方式是以字符串格式,但每个食谱都被包含在自己的{大括号}中,所以我在想是否有一种方法可以在考虑到这一点的情况下操作数据(也许与数组有关?),但我一直没有能够找到任何方法。无论如何,我将包含我的代码以及API返回的示例。

以下是responseString的外观:

[{"title": "Recipe 1", "ingredients": "blah", "instructions": "blah"}, {"title": "recipe 2", 等等}]
class RecipeTest {
    public static void main(String[] args) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://recipe-by-api-ninjas.p.rapidapi.com/v1/recipe?query=chocolate%20chip%20cookies"))
                .header("X-RapidAPI-Key", "myApiKey")
                .header("X-RapidAPI-Host", "theApiHost")
                .method("GET", HttpRequest.BodyPublishers.noBody())
                .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        String responseString = response.body();

        List<Recipe> recipeList = parseResponse(new ArrayList<Recipe>(), responseString.replaceAll("\"", ""), 0);

        System.out.println(recipeList.get(0).print());
        System.out.println(recipeList.get(1).print());
        System.out.println(recipeList.get(2).print());
        System.out.println(recipeList.size());
    }

    static List<Recipe> parseResponse(ArrayList<Recipe> recipes, String s, int begin) {
        try {
            int titleBeginIndex = s.indexOf("title:", begin);
            int titleEndIndex = s.indexOf(",", titleBeginIndex);

            int ingredientsBeginIndex = s.indexOf("ingredients:", titleEndIndex);
            int ingredientsEndIndex = s.indexOf(",", ingredientsBeginIndex);

            int servingsBeginIndex = s.indexOf("servings:", ingredientsEndIndex);
            int servingsEndIndex = s.indexOf(",", servingsBeginIndex);

            int instructionsBeginIndex = s.indexOf("instructions:", servingsEndIndex);
            int instructionsEndIndex = s.indexOf("}", instructionsBeginIndex);

            String title = s.substring(titleBeginIndex, titleEndIndex);
            String ingredients = s.substring(ingredientsBeginIndex, ingredientsEndIndex);
            String servings = s.substring(servingsBeginIndex, servingsEndIndex);
            String instructions = s.substring(instructionsBeginIndex, instructionsEndIndex);

            recipes.add(new Recipe(title, ingredients, servings, instructions));

            parseResponse(recipes, s, ingredientsEndIndex);
        } finally {
            return recipes;
        }
    }
}

我只是在寻找一种更干净的方法来解析数据为Recipe对象的数组或列表。我的Try... Finally块能够工作,但我觉得我没有以正确的方式进行处理。

英文:

I'm working on a Recipe app in the very early stages. I've never used API's before but I get the basic understanding of it, I have done A LOT of searching to get this far but basically here's the deal: I'm using a Recipe API from RapidAPI that can return multiple responses. I would like to parse all of the responses into objects of my Recipe class. I have got the code working and functional but I feel like there has to be a better way of accomplishing what I am trying to do. I am currently using a function to parse the String into an ArrayList of Recipe objects using a Try Catch block to terminate when it hits the index out of bounds exception.

The way Rapid API sends the information over is in string format but each recipe is enclosed in its own {curly braces} so I was wondering if there wasn't some way to manipulate the data with that in mind(maybe something with an array?) but haven't been able to figure anything out. Anyways I'm going to include my code and I will also include a sample of what is returned from the API.

responseString looks like this:

[{"title": "Recipe 1", "ingredients": "blah", "instructions": "blah"}, {"title": "recipe 2", etc}]
class RecipeTest {
public static void main(String[] args) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://recipe-by-api-ninjas.p.rapidapi.com/v1/recipe?query=chocolate%20chip%20cookies"))
.header("X-RapidAPI-Key", "myApiKey")
.header("X-RapidAPI-Host", "theApiHost")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
String responseString = response.body();
List<Recipe> recipeList = parseResponse(new ArrayList<Recipe>(), responseString.replaceAll("\"", ""), 0);
System.out.println(recipeList.get(0).print());
System.out.println(recipeList.get(1).print());
System.out.println(recipeList.get(2).print());
System.out.println(recipeList.size());
}
static List<Recipe> parseResponse(ArrayList<Recipe> recipes, String s, int begin) {
try {
int titleBeginIndex = s.indexOf("title:", begin);
int titleEndIndex = s.indexOf(",", titleBeginIndex);
int ingredientsBeginIndex = s.indexOf("ingredients:", titleEndIndex);
int ingredientsEndIndex = s.indexOf(",", ingredientsBeginIndex);
int servingsBeginIndex = s.indexOf("servings:", ingredientsEndIndex);
int servingsEndIndex = s.indexOf(",", servingsBeginIndex);
int instructionsBeginIndex = s.indexOf("instructions:", servingsEndIndex);
int instructionsEndIndex = s.indexOf("}", instructionsBeginIndex);
String title = s.substring(titleBeginIndex, titleEndIndex);
String ingredients = s.substring(ingredientsBeginIndex, ingredientsEndIndex);
String servings = s.substring(servingsBeginIndex, servingsEndIndex);
String instructions = s.substring(instructionsBeginIndex, instructionsEndIndex);
recipes.add(new Recipe(title, ingredients, servings, instructions));
parseResponse(recipes, s, ingredientsEndIndex);
} finally {
return recipes;
}
}
}

I am just looking for a cleaner way to parse the data in an array or list of Recipe Objects. My Try... Finally block works but I feel like I'm not doing it the proper way.

答案1

得分: 0

有一些工具可以帮助你解析 JSON 字符串,比如 JacksonGson

我用 Jackson 写了一段示例代码,希望能对你有所帮助。

要了解更多关于如何使用 Jackson 的方法,你需要自己学习。

public static void main(String[] args) throws Exception {
    String responseString = "[{\"title\": \"Recipe 1\", \"ingredients\": \"blah\", \"instructions\": \"blah\"}, {\"title\": \"recipe 2\"}]";
    List<Recipe> recipeList = parseResponse(responseString);
    for (Recipe recipe : recipeList) {
        System.out.println(recipe);
    }
}

static List<Recipe> parseResponse(String s) {
    ObjectMapper mapper = new ObjectMapper();
    try {
        return mapper.readValue(s, new TypeReference<List<Recipe>>() {});
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new ArrayList<>();
}

static class Recipe {
    String title;
    String ingredients;
    String servings;
    String instructions;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getIngredients() {
        return ingredients;
    }

    public void setIngredients(String ingredients) {
        this.ingredients = ingredients;
    }

    public String getServings() {
        return servings;
    }

    public void setServings(String servings) {
        this.servings = servings;
    }

    public String getInstructions() {
        return instructions;
    }

    public void setInstructions(String instructions) {
        this.instructions = instructions;
    }

    @Override
    public String toString() {
        return "Recipe{" +
                "title='" + title + '\'' +
                ", ingredients='" + ingredients + '\'' +
                ", servings='" + servings + '\'' +
                ", instructions='" + instructions + '\'' +
                '}';
    }
}
英文:

There are some tools can help you to pares json string like Jackson,Gson.

I wrote a sample code with Jackson,hope it can help you.

For more ways to use Jackson, you need to learn for yourself.

public static void main(String[] args)  throws Exception{
String responseString = &quot;[{\&quot;title\&quot;: \&quot;Recipe 1\&quot;, \&quot;ingredients\&quot;: \&quot;blah\&quot;, \&quot;instructions\&quot;: \&quot;blah\&quot;}, {\&quot;title\&quot;: \&quot;recipe 2\&quot;}]&quot;;
List&lt;Recipe&gt; recipeList = parseResponse( responseString);
for (Recipe recipe : recipeList) {
System.out.println(recipe);
}
}
static List&lt;Recipe&gt; parseResponse( String s )  {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(s, new TypeReference&lt;List&lt;Recipe&gt;&gt;() {
});
}catch (Exception e) {
e.printStackTrace();
}
return new ArrayList&lt;&gt;();
}
static class Recipe{
String title;
String ingredients;
String servings;
String instructions;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIngredients() {
return ingredients;
}
public void setIngredients(String ingredients) {
this.ingredients = ingredients;
}
public String getServings() {
return servings;
}
public void setServings(String servings) {
this.servings = servings;
}
public String getInstructions() {
return instructions;
}
public void setInstructions(String instructions) {
this.instructions = instructions;
}
@Override
public String toString() {
return &quot;Recipe{&quot; +
&quot;title=&#39;&quot; + title + &#39;\&#39;&#39; +
&quot;, ingredients=&#39;&quot; + ingredients + &#39;\&#39;&#39; +
&quot;, servings=&#39;&quot; + servings + &#39;\&#39;&#39; +
&quot;, instructions=&#39;&quot; + instructions + &#39;\&#39;&#39; +
&#39;}&#39;;
}
}

huangapple
  • 本文由 发表于 2023年6月19日 09:15:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定