IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

Consommer du JSON avec un @RestController


Sujet :

Spring Java

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 065
    Points : 2 567
    Points
    2 567
    Par défaut Consommer du JSON avec un @RestController
    Bonjour,

    Je poste ici car ma question porte sur plusieurs briques, de Spring mais surtout sur Spring MVC.

    Je voudrais créer des services web pour ajouter des entity depuis du JSON, le service avec des paramètres standards fonctionne.

    J'ai fait un code teste.

    J'ai une entité Personne que je souhaite créer depuis un service.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Entity
    @JsonRootName("personne	")
    public class Personne {
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	@JsonIgnore
    	private int id;
        @JsonProperty("nom")
    	private String nom;
        @JsonProperty("prenom")
    	private String prenom;
    Comme l'id est généré, je ne souhaite pas l'récupérer dans les arguments, c'est pourquoi j'ai mis l'annotation "ignore".

    J'ai ajouté deux services un pour récupérer un nouvel item et un autre pour en récupérer plusieurs à la fois les deux depuis du JSON.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    	@PostMapping(path = "consume", consumes="application/json")
    	@ResponseStatus(code = HttpStatus.CREATED)
    	public void saveJSON(@RequestBody Personne personne) {
    LOGGER.debug("Personne founf : " + personne, null, personne, personne, personne, personne, personne, personne, personne, personne);
     
    		personneService.save(personne);
    	}
     
    	@PostMapping(path = "/consumeAll", consumes = "application/json")
    	public HttpStatus saveAllJSON(@RequestBody List<Personne> personnes) {
    LOGGER.debug("Personne founf : " + personnes.size());
     
    		personneService.saveAll(personnes);
     
    		return HttpStatus.CREATED;
    	}
    Je tente de contacter mon service avec curl car postman n'est pas très accessible pour moi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    curl -H "Content-type: application/json" -d '{"id":"1","nom":"smith","prenom":"john"}' http://localhost:8080/personne/consume
    Mais j'obtiens toujours une erreur 400.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    {"timestamp":"2022-11-18T10:13:22.547+00:00","status":400,"error":"Bad Request","trace":"org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:391)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:160)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:133)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:696)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:779)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\nCaused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]\r\n\tat com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2391)\r\n\tat com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:735)\r\n\tat com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:659)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2737)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:902)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:794)\r\n\tat com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761)\r\n\tat com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667)\r\n\tat com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3682)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:380)\r\n\t... 51 more\r\n","message":"JSON parse error: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]","path":"/personne/consume"}
    Est-ce que j'ai mal mappé l'uurl ?
    Est-ce que je peux ignorer l'id dans les paramètres ? Car JPA qui va le définir pour moi.

    Cordialement
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 453
    Points : 883
    Points
    883
    Billets dans le blog
    5
    Par défaut
    Il faut différentier les couche (à minima), et surtout les responsabilités de chaque classes.

    Le REST n'a rien à voir avec le service et la DAO.

    Je pense même qu'il faut différentier la DTO (à transfèrer) et l'entité (qui mappe la BDD, en résumé Hibernate).

    Si tu passe un simple POJO à la con (qui du coup est une DTO), et sans annotation, ça marchera.

    A toi d'appeler le service dans le controller, et dans le service, dans lequel tu injectes la DAO, faire le mapping et sauver.

  3. #3
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 065
    Points : 2 567
    Points
    2 567
    Par défaut
    Merci pour ta réponse.

    Là je ne comprends pas j'pensais avoir séparé les couches.

    J'ai une classe par annotation Spring
    - @Entity pour mon modèle , qui ne connais pas les autres.
    - @Repository, qui dérive de CrudRepository, qui se base sur le modèle
    - @Service qui appelle le repository
    - Le @RestController, qui fait appelle au service

    Il n'y a pas de méllange.

    Je pensais qu'Spring pouvait créer recréer mes objet avec RequestBody

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    @RestController
    @RequestMapping("/personne")
    @CrossOrigin
    public class PersonneWebService {
    	private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(PersonneService.class);
    	@Autowired
    	private PersonneService personneService;
     
    	@GetMapping("/get{id}")
    	public ResponseEntity<Personne> getById(@RequestParam(required = true) Integer id) {
    		Optional<Personne> mayBePersonne = personneService.getById(id);
     
    		if (mayBePersonne.isPresent()) {
    			return new ResponseEntity<Personne>(mayBePersonne.get(), HttpStatus.FOUND);
    		} else {
    			return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    		}
    	}
     
    	@GetMapping(value = "/getAll")
    	public ResponseEntity<List<Personne>> getAll() {
    		return new ResponseEntity<List<Personne>>(personneService.getAll(), HttpStatus.FOUND);
    	}
     
    	@PostMapping(value = "/create")
    	public HttpStatus save(@RequestParam(name = "nom", required = true) String nom,
    			@RequestParam(name = "prenom", required = true) String prenom) {
    		Personne personne = new Personne(nom, prenom);
     
    		personneService.save(personne);
     
    		return HttpStatus.CREATED;
     
    //			return HttpStatus.NOT_ACCEPTABLE;
    	}
     
    	@PostMapping(path = "consume", consumes="application/json")
    	@ResponseStatus(code = HttpStatus.CREATED)
    	public void saveJSON(@RequestBody Personne personne) {
    LOGGER.debug("Personne founf : " + personne, null, personne, personne, personne, personne, personne, personne, personne, personne);
     
    		personneService.save(personne);
    	}
     
    	/*
    	@PostMapping(path = "/consumeAll", consumes = "application/json")
    //	@ResponseStatus(code = HttpStatus.CREATED)
    	public HttpStatus saveAllJSON(@RequestBody List<Personne> personnes) {
    LOGGER.debug("Personne founf : " + personnes.size());
     
    		personneService.saveAll(personnes);
     
    		return HttpStatus.CREATED;
    	}
     
     
    	@DeleteMapping(value = "/delete")
    	public HttpStatus delete(@RequestParam(value = "id", required = true) int id) {
    		Optional<Personne> mayBePersonne = personneService.getById(id);
     
    		if (mayBePersonne.isPresent()) {
    			personneService.delete(mayBePersonne.get());
     
    			return HttpStatus.OK;
    		} else {
    			return HttpStatus.NOT_FOUND;
    		}
    	}
     
    }
    Cordialement
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 453
    Points : 883
    Points
    883
    Billets dans le blog
    5
    Par défaut
    Comme je n'aime pas me répéter, sur mon projet perso, j'ai fait un template Method (c'est un Design pattern), et ça marche sans problème:

    https://bitbucket.org/philippegibaul...ontroller.java

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    package com.calculateur.warhammer.rest.controller;
     
    import java.util.List;
     
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
     
    import com.calculateur.warhamer.service.contrat.IServiceAvecRecherche;
    import com.calculateur.warhammer.base.dto.ILibelleDTO;
    import com.calculateur.warhammer.base.exception.FunctionnalExeption;
    import com.calculateur.warhammer.base.exception.ServiceException;
    import com.calculateur.warhammer.dto.recherche.RechercheInService;
     
    /**
     * Template Méthode pour les controlleur avec recherche paramétrée
     * @author phili
     *
     * @param <D> Type de DTO
     * @param <S> Type de Service
     */
    public abstract class AbstractListAvecRechercheRestController<D extends ILibelleDTO,S extends IServiceAvecRecherche<D>> extends AbstractListRestController<D, S>{
     
    	@PostMapping(value = "/parRecherche", consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
    	public ResponseEntity<List<D>> getByRecherche(@RequestBody RechercheInService recherche)throws ServiceException,FunctionnalExeption{
    		return ResponseEntity.ok(getService().listeAvecParametresRecherche(recherche));
    	}
    }
    Par contre, pour ton get, je pense qu'il y a peut être un problème.

    Remplace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @GetMapping("/get{id}")
    Par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @GetMapping("/get/{id}")

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 453
    Points : 883
    Points
    883
    Billets dans le blog
    5
    Par défaut
    Par contre, et en fait, c'est ça le sens de ma remarque précédente, évite de mélanger le JSON avec @Entity.


    @Entity, c'est pour la base de données. Json, c'est dans la DTO, c'est ce que tu transferts vers l'extérieure.

    Et la DTO marche sans @JsonProperty("nom").

    Cordialement.

  6. #6
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 065
    Points : 2 567
    Points
    2 567
    Par défaut
    Bonjour,

    Désolé pour le retard mais j'ai eu un petit contre-temps.

    Après avoir fait un tour ici
    https://www.baeldung.com/java-dto-pattern

    Bon je suis d'accord sur le principe du DTO.
    Mais pour l'instant si je crée un DTO il sera identique à mon objet métier, car je n'ai rien à cacher comme un mot de passe ou une propriété sensible et même pas de méthodes à cacher.

    C'est juste que je n'arrive pas à créer une méthode qui accepte un tableau en argument pour créer plusieur entités depuis le JSON

    Cordialement
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 453
    Points : 883
    Points
    883
    Billets dans le blog
    5
    Par défaut
    Le problème, c'est que le métier de codeur évolue vite et on est passé à l'architecture hexagonale pour se centrer sur le métier.

    https://www.baeldung.com/hexagonal-a...ure-ddd-spring

    Sans aller sur l'architecture hexagonale qui, il est vrai que ça peut devenir compliqué et peu adapté si le métier est facile ou inexistant, on peut améliorer le principe de l'architecture en couche.

    On fait proprement la BDD via JPA qui mappe toute la BDD.

    La DTO devient donc une simplification de la BDD, puisque l'on fait des coupes et que l'on s'intéresse qu'à ce qui sort.

    Tu trouvera ici de très bon cours sur les Micro-services où la question Mammouth Monolithique/Micro service/Entité/DTO est abordé:
    https://www.youtube.com/@mohamedYoussfi/videos

    Cordialement.

Discussions similaires

  1. Prise en main de JSON avec GWT
    Par GroXx dans le forum GWT et Vaadin
    Réponses: 5
    Dernier message: 05/02/2009, 12h47
  2. [POO] parcourir un objet json avec une boucle for in
    Par bucheron007 dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 19/01/2009, 12h55
  3. Création de fichier json avec PHP
    Par versus68 dans le forum Langage
    Réponses: 1
    Dernier message: 02/06/2008, 11h56
  4. Consommation mémoire hallucinante avec glob()
    Par mobscene dans le forum Langage
    Réponses: 8
    Dernier message: 24/01/2007, 18h29
  5. [AJAX] Récupération d'un fichier JSON avec javaScript
    Par guerin dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/11/2006, 19h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo