Parsing Java
Résolu/Fermé
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
-
Modifié le 22 sept. 2020 à 11:43
gloria5739 Messages postés 43 Date d'inscription lundi 21 septembre 2020 Statut Membre Dernière intervention 21 janvier 2022 - 2 déc. 2020 à 09:19
gloria5739 Messages postés 43 Date d'inscription lundi 21 septembre 2020 Statut Membre Dernière intervention 21 janvier 2022 - 2 déc. 2020 à 09:19
A voir également:
- Org.json.jsonexception: jsonobject[""] not found.
- Waptrick java football - Télécharger - Jeux vidéo
- Jeux java itel football - Télécharger - Jeux vidéo
- Java apk - Télécharger - Langages
- Waptrick java voiture - Télécharger - Jeux vidéo
- Java décompiler - Télécharger - Langages
4 réponses
Reivax962
Messages postés
3672
Date d'inscription
jeudi 16 juin 2005
Statut
Membre
Dernière intervention
11 février 2021
1 011
22 sept. 2020 à 11:54
22 sept. 2020 à 11:54
Bonjour,
Deux cas.
Soit ton JSON est déjà trié par Project et par List.
C'est le cas simple : il te suffit de stocker la valeur précédente de ces champs, et de ne faire println que s'ils ont changé.
Soit ton JSON n'est pas trié, auquel cas tu ne dois rien afficher au fur et à mesure du parsing, mais tout stocker dans une structure adaptée (je ne maîtrise pas assez les collections et listes en Java pour te dire quelle est la meilleure) pour, ensuite, trier et parcourir tout ça pour les afficher.
Xavier
Deux cas.
Soit ton JSON est déjà trié par Project et par List.
C'est le cas simple : il te suffit de stocker la valeur précédente de ces champs, et de ne faire println que s'ils ont changé.
Soit ton JSON n'est pas trié, auquel cas tu ne dois rien afficher au fur et à mesure du parsing, mais tout stocker dans une structure adaptée (je ne maîtrise pas assez les collections et listes en Java pour te dire quelle est la meilleure) pour, ensuite, trier et parcourir tout ça pour les afficher.
Xavier
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
22 sept. 2020 à 19:51
22 sept. 2020 à 19:51
Bonjour,
Tout d'abord quand tu utilises des librairies tierces, il est important de préciser lesquelles, ou au moins les imports correspondants, parce que dans ton code si j'arrive à deviner que JSONObject et JSONArray viennent de org.json, on peut quand même se poser des questions sur JSONParser (d'où vient-il ?) ou sur la méthode size() de JSONArray qui n'existe pas (c'est length), ce qui laisse à penser que ton code ne compile pas, ou que tu utilises d'autres librairies.
De plus, Java est un langage objet, pour manipuler tes données, tu dois créer des classes, notamment ici pour représenter les données du Json, dans des DTO (Data Transfert Object).
Exemple :
Ton Parser peut alors se réécrire comme ceci :
Une petite classe de test, pour vérifier que ça fonctionne bien :
Ton problème, c'est que cette représentation correspond au Json, pas à ce que tu souhaites manipuler, il faut donc créer d'autres objets, qui correspondent à ce que tu veux en faire.
Il faut ensuite faire le mapping entre les DTO et les Bean, c'est là que tu vas devoir faire des regroupements, en l’occurrence sur le HeaderBean, grâce à une Map par exemple.
Si on adapte la méthode main, on peut reproduire l'affichage que tu souhaitais :
Avec ce résultat, comme attendu :
Tout d'abord quand tu utilises des librairies tierces, il est important de préciser lesquelles, ou au moins les imports correspondants, parce que dans ton code si j'arrive à deviner que JSONObject et JSONArray viennent de org.json, on peut quand même se poser des questions sur JSONParser (d'où vient-il ?) ou sur la méthode size() de JSONArray qui n'existe pas (c'est length), ce qui laisse à penser que ton code ne compile pas, ou que tu utilises d'autres librairies.
De plus, Java est un langage objet, pour manipuler tes données, tu dois créer des classes, notamment ici pour représenter les données du Json, dans des DTO (Data Transfert Object).
Exemple :
import java.util.List; public class ItemDto { public String content; public String projectName; public String todoListName; public List<TaskDto> subTasks; public String toString(){ return "ItemDto [content=" + content + ", projectName=" + projectName + ", todoListName=" + todoListName + ", subTasks=" + subTasks + "]"; } }
public class TaskDto { public String content; public String projectName; public String todoListName; public String toString(){ return "TaskDto [content=" + content + ", projectName=" + projectName + ", todoListName=" + todoListName + "]"; } }
Ton Parser peut alors se réécrire comme ceci :
import java.util.*; import org.json.*; public class Parser { public static List<ItemDto> readJson(String json) { JSONObject rootJson = new JSONObject(json); JSONArray itemsJson = (JSONArray) rootJson.get("todo-items"); List<ItemDto> items = new ArrayList<>(itemsJson.length()); for (int i = 0; i < itemsJson.length(); i++) { items.add(readItem((JSONObject) itemsJson.get(i))); } return items; } public static ItemDto readItem(JSONObject itemJson) { ItemDto item = new ItemDto(); item.content = itemJson.getString("content"); item.projectName = itemJson.getString("project-name"); item.todoListName = itemJson.getString("todo-list-name"); JSONArray tasksJson = (JSONArray) itemJson.get("subTasks"); item.subTasks = new ArrayList<>(tasksJson.length()); for (int i = 0; i < tasksJson.length(); i++) { item.subTasks.add(readTask((JSONObject) tasksJson.get(i))); } return item; } public static TaskDto readTask(JSONObject taskJson) { TaskDto task = new TaskDto(); task.content = taskJson.getString("content"); task.projectName = taskJson.getString("project-name"); task.todoListName = taskJson.getString("todo-list-name"); return task; } }
Une petite classe de test, pour vérifier que ça fonctionne bien :
import java.nio.file.*; import java.util.List; public class Test { public static void main(String[] args) throws Exception { List<ItemDto> items = Parser.readJson(Files.readString(Paths.get("E:/test.json"))); System.out.println(items); } }
Ton problème, c'est que cette représentation correspond au Json, pas à ce que tu souhaites manipuler, il faut donc créer d'autres objets, qui correspondent à ce que tu veux en faire.
import java.util.List; public class ProjectBean { public HeaderBean header; public List<ItemBean> items; public String toString(){ return "ProjectBean [header=" + header + ", items=" + items + "]"; } }
import java.util.Objects; public class HeaderBean { public String projectName; public String todoListName; public String toString(){ return "HeaderBean [projectName=" + projectName + ", todoListName=" + todoListName + "]"; } public int hashCode(){ return Objects.hash(projectName, todoListName); } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; HeaderBean other = (HeaderBean) obj; return Objects.equals(projectName, other.projectName) && Objects.equals(todoListName, other.todoListName); } }
import java.util.List; public class ItemBean { public String content; public List<String> subTasksContent; public String toString(){ return "ItemBean [content=" + content + ", subTasksContent=" + subTasksContent + "]"; } }
Il faut ensuite faire le mapping entre les DTO et les Bean, c'est là que tu vas devoir faire des regroupements, en l’occurrence sur le HeaderBean, grâce à une Map par exemple.
import java.util.*; public class ProjectMapper { public static List<ProjectBean> projectsFromItems(List<ItemDto> itemDtos) { Map<HeaderBean, List<ItemBean>> map = new HashMap<>(); for (ItemDto itemDto : itemDtos) { HeaderBean headerBean = new HeaderBean(); headerBean.projectName = itemDto.projectName; headerBean.todoListName = itemDto.todoListName; ItemBean itemBean = new ItemBean(); itemBean.content = itemDto.content; itemBean.subTasksContent = new ArrayList<>(); for (TaskDto taskDto : itemDto.subTasks) { itemBean.subTasksContent.add(taskDto.content); } List<ItemBean> itemBeans = map.get(headerBean); if (itemBeans == null) { itemBeans = new ArrayList<>(); map.put(headerBean, itemBeans); } itemBeans.add(itemBean); } List<ProjectBean> projects = new ArrayList<>(); for (Map.Entry<HeaderBean, List<ItemBean>> entry : map.entrySet()) { ProjectBean project = new ProjectBean(); project.header = entry.getKey(); project.items = entry.getValue(); projects.add(project); } return projects; } }
Si on adapte la méthode main, on peut reproduire l'affichage que tu souhaitais :
public static void main(String[] args) throws Exception { List<ItemDto> items = Parser.readJson(Files.readString(Paths.get("E:/test.json"))); List<ProjectBean> projects = ProjectMapper.projectsFromItems(items); for (ProjectBean project : projects) { System.out.println("Project : " + project.header.projectName); System.out.println("List : " + project.header.todoListName); for (ItemBean item : project.items) { System.out.println("Content : " + item.content); for (String subTask : item.subTasksContent) { System.out.println("sous tâches : " + subTask); } } } }
Avec ce résultat, comme attendu :
Project : Governance and Follow-up SII
Liste : Teamwork
Content : Reporting Teamwork: récupérer travaux API (30%)
sous tâches : HTTP request
sous tâches : Proxy configuration
Content : Reporting Teamwork: récupérer travaux API (60%)
sous tâches : Authentication API
sous tâches : Parsing
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
23 sept. 2020 à 14:58
23 sept. 2020 à 14:58
Bonjour KX,
Merci beaucoup, ton code fonctionne parfaitement ! Tu me sauves la vie
Merci beaucoup, ton code fonctionne parfaitement ! Tu me sauves la vie
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
28 sept. 2020 à 16:30
28 sept. 2020 à 16:30
Bonjur KX, j'aurai une autre question.
Je viens de tester mon api mais avec d'autres paramètres (en l’occurrence la date des tâches). Certaine tâches n'ont pas de sous tâches, et lorsque j'appelle des tâches sans sous tâches, mon application me renvoie l'erreur suivante :
GRAVE: "Servlet.service()" pour la servlet [jsp] a lancé une exception
org.json.JSONException: JSONObject["subTasks"] not found.
En effet, lorsque je regarde la reponse brute en JSON, le nom "subtasks" n'y est pas. Je pensais qu'elle y serai mais avec une valeur null mais même pas...
Tu aurais une idée ?
Merci
Je viens de tester mon api mais avec d'autres paramètres (en l’occurrence la date des tâches). Certaine tâches n'ont pas de sous tâches, et lorsque j'appelle des tâches sans sous tâches, mon application me renvoie l'erreur suivante :
GRAVE: "Servlet.service()" pour la servlet [jsp] a lancé une exception
org.json.JSONException: JSONObject["subTasks"] not found.
En effet, lorsque je regarde la reponse brute en JSON, le nom "subtasks" n'y est pas. Je pensais qu'elle y serai mais avec une valeur null mais même pas...
Tu aurais une idée ?
Merci
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
>
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
28 sept. 2020 à 17:32
28 sept. 2020 à 17:32
C'est le comportement normal des JSONObject, lorsque l'attribut demandé n'existe pas cela provoque une JSONException.
Dans ce cas tu peux faire un try/catch pour gérer un comportement alternatif lorsque l'attribut est manquant.
Dans ce cas tu peux faire un try/catch pour gérer un comportement alternatif lorsque l'attribut est manquant.
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
6 oct. 2020 à 10:21
6 oct. 2020 à 10:21
Re Bonjour,
J'ai essayé mais ça fait 1 semaine que je bloque, tu aurais une idée de comment faire ?
Merci
J'ai essayé mais ça fait 1 semaine que je bloque, tu aurais une idée de comment faire ?
Merci
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
6 oct. 2020 à 19:13
6 oct. 2020 à 19:13
Bonjour,
Je t'ai déjà expliqué comment faire, tu dois ajouter un try/catch et gérer un comportement alternatif lorsque l'attribut est manquant.
Par exemple :
Je t'ai déjà expliqué comment faire, tu dois ajouter un try/catch et gérer un comportement alternatif lorsque l'attribut est manquant.
Par exemple :
try { JSONArray tasksJson = (JSONArray) itemJson.get("subTasks"); item.subTasks = new ArrayList<>(tasksJson.length()); ... } catch (JSONException e) { // subTasks n'existe pas item.subTasks = new ArrayList<>(); }
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
>
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
2 déc. 2020 à 09:19
2 déc. 2020 à 09:19
Re Bonjour KX,
J'aurai une autre question, j'aurai besoin de cette fois ci filtrer mes tâches, exemple : récupérer seulement les tâches avec "Teamwork" comme "todo-list-name", je ne trouve pas du tout comment faire...
J'aurai une autre question, j'aurai besoin de cette fois ci filtrer mes tâches, exemple : récupérer seulement les tâches avec "Teamwork" comme "todo-list-name", je ne trouve pas du tout comment faire...
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
7 oct. 2020 à 09:39
7 oct. 2020 à 09:39
Bonjour KX,
Merci beaucoup, en effet j'avais laisser la partie dans le catch vide.
Merci beaucoup, en effet j'avais laisser la partie dans le catch vide.
gloria5739
Messages postés
43
Date d'inscription
lundi 21 septembre 2020
Statut
Membre
Dernière intervention
21 janvier 2022
1
14 oct. 2020 à 11:15
14 oct. 2020 à 11:15
Re Bonjour KX,
J'aurai une autre question, j'aurai besoin de cette fois ci filtrer mes tâches, exemple : récupérer seulement les tâches avec "Teamwork" comme "todo-list-name", je ne trouve pas du tout comment faire...
J'aurai une autre question, j'aurai besoin de cette fois ci filtrer mes tâches, exemple : récupérer seulement les tâches avec "Teamwork" comme "todo-list-name", je ne trouve pas du tout comment faire...
22 sept. 2020 à 14:24
Merci pour ta réponse,
Qu'est ce que tu entends par "Soit ton JSON est déjà trié par Project et par List" ?
Gloria
22 sept. 2020 à 15:07
Mais ça ne peut marcher que si ton JSON est de la forme :
Et non pas
Car dans ce cas, on change de Project et de List avant d'avoir écrit toutes les sous-rubriques de ces projets/listes.
Donc il faut que le JSON soit déjà ordonné par ces champs-là.
Xavier