44 votes

Spring 3.2.x (Web MVC) API REST et demandes JSON2 Post, comment y arriver une fois pour toutes?

Avant de rentrer dans les détails, je sais qu'il y a eu beaucoup de conversations et des questions connexes sur Stackoverflow. Toutes sortes de m'aider de différentes façons j'ai donc pensé que j'ai mis mes découvertes tous ensemble comme une unique organisé FAQ pour résumer mes conclusions.

Des Concepts Liés À L'

Vous connaissez sûrement sur ces, mais je viens de les écrire comme un examen rapide. N'hésitez pas à modifier dans le cas où quelque chose m'échappe.

Requête HTTP POST:

Une requête post est utilisé lorsque vous êtes prêt à envoyer un objet à un service web ou une de votre côté serveur de l'application.

La sérialisation:

Est le processus d'obtention de l'objet à partir de votre navigateur web par le biais de votre côté serveur de l'application. Un appel Ajax jQuery ou une boucle de la requête post peut être utilisé.

La sérialisation des protocoles:

Les plus populaires sont ceux qui thèses jours sont JSON et XML. XML est en train de devenir de moins en moins populaire que xml sérialisé objets sont relativement plus grand en taille, en raison de la nature de balises XML. Dans ce document, l'accent est mis JSON2 de sérialisation.

Printemps:

Spring framework et son puissant annotation permet d'exposer service web de manière efficace. Il ya beaucoup de différentes bibliothèques au Printemps. Celui qui est notre objectif ici est web Spring MVC.

Curl vs JQuery:

Ce sont les outils que vous pouvez utiliser pour faire une requête post à votre côté client. Même si vous prévoyez d'utiliser JQuery ajax appel, je vous suggère d'utiliser Curl pour des fins de débogage comme il vous fournit une réponse détaillée après avoir fait la requête post.

@RequestBody vs @RequestParam/@PathVariable vs @ModelAttribute:

Dans le cas où vous avez un web service qui n'est pas selon votre Java EE modèle, @RequestBody doit être utilisé. Si vous utilisez le modèle et votre objet JSON est ajouté au modèle, vous pouvez accéder à l'objet via @ModelAttribute. Seulement pour les cas où votre requête est une requête GET ou un POST et GET demande combinaison vous aurez besoin d'utiliser @RequestParam/@PathVariable.

@RequestBody vs @ResposeBody:

Comme vous pouvez le voir à partir du nom, il est aussi simple que cela, vous avez seulement besoin de l' @ResponseBody si vous êtes d'envoyer une réponse au client après le côté serveur de la méthode traité la demande.

RequestMappingHandlerAdapter vs AnnotationMethodHandlerAdapter:

RequestMappingHandlerAdapter est le nouveau gestionnaire de mappage pour le Printemps-cadre, qui a remplacé AnnotationMethodHandlerAdapter depuis le Printemps 3.1. Si votre configuration existante est toujours en AnnotationMethodHandlerAdapter vous trouverez peut-être ce post utile. La config fourni dans mon post va vous donner une idée sur comment configurer le RequestMappingHandlerAdapter.

Le programme d'installation

Vous aurez besoin de configurer un message de convertisseur. C'est comment votre JSON sérialisé corps du message est converti en un objet java à votre côté serveur.

La Configuration de base à partir d' ici. Les convertisseurs ont été MarshallingHttpMessageConverter et CastorMarshaller dans la configuration de base de l'échantillon, je l'ai remplacé avec MappingJackson2HttpMessageConverter et MappingJacksonHttpMessageConverter.

Où mettre la configuration

La façon dont mon projet est mis en place, j'ai deux fichiers de configuration:

  • Le Contexte de l'Application XML: Un il le contexte de l'application fichier XML où votre sessionFactory de haricot, de la source de données de haricots, etc. sont situés.
  • MVC Répartiteur Servlet, XML: C'est là que vous avez votre point de vue résolveur de haricots et de l'importation de votre contexte de l'application XML.

hadlerAdapter bean doit être situé dans le plus tard, c'est le MVC Répartiteur fichier XML.

<bean name="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
            <ref bean="jsonConverter"/>

        </list>

    </property>
    <property name="requireSession" value="false"/>

</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json"/>
</bean>

Vous pouvez avoir plusieurs message de fumées. ici, j'ai créé un normal JSON ainsi qu'un JSON 2 message transformateur. Les deux Ref et normal bean format dans le fichier XML ont été utilisés (personnellement je préfère la ref balise comme son plus propre).

API REST

Voici un exemple de contrôleur qui est d'exposer l'API REST.

Le contrôleur

C'est là que votre API REST pour une requête HTTP de type post est exposée.

@Component
@Controller
@RequestMapping("/api/user")
public class UserController {
@RequestMapping(value = "/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String insertUser(@RequestBody final User user) {
    System.out.println(user.toString());
    userService.insertUser(user);
    String userAdded = "User-> {" + user.toString() + "} is added";
    System.out.println(userAdded);
        return userAdded;
    }
}

L'Objet Java

@JsonAutoDetect
public class User {

private int id;
private String username;
private String name;
private String lastName;
private String email;

public int getId() {
    return externalId;
}

public void setId(final int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(final String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(final String email) {
    this.email = email;
}
public String getUsername() {
    return username;
}

public void setUsername(final String username) {
    this.username = username;
}

public String getLastName() {
    return lastName;
}

public void setLastName(final String lastName) {
    this.lastName = lastName;
}

@Override
public String toString() {
    return this.getName() + " | " + this.getLastName()  + " | " + this.getEmail()
            + " | " + this.getUsername()  + " | " + this.getId()  + " | ";
    }

}

CURL appel Post

curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

Related posts et des questions

Cette FAQ n'a pas été possible si elle n'était pas pour toutes les personnes qui ont fourni les postes suivants et des questions (cette liste élargir si je viens à travers utiles related posts/questions):

  1. Quelle est la correcte JSON type de contenu?
  2. Spring 3.0 prise de réponse JSON à l'aide de jackson message convertisseur
  3. Comment publier des données JSON avec Curl à partir de la Borne/ligne de commande pour Tester Printemps RESTE?
  4. Affichage JSON à l'API REST
  5. https://github.com/geowarin/spring-mvc-examples
  6. Comment publier JSON en PHP avec curl
  7. Printemps de REPOS | MappingJacksonHttpMessageConverter produit invalid JSON
  8. https://github.com/eugenp/REST
  9. Web Spring MVC - valider la demande individuelle params
  10. Comment publier des données JSON avec Curl à partir de la Borne/ligne de commande pour Tester Printemps RESTE?
  11. Comment voulez-vous retourner un objet JSON à partir d'une Servlet Java
  12. Quel type MIME si JSON est retourné par une API REST?

12voto

AmirHd Points 1004

CURL appel Post

curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

Différents Scénarios D'Erreur:

Ici, j'explore les différentes erreurs que vous pourriez rencontrer après avoir effectué une boucle d'appel et de ce qui pourrait peut-être mal tourné.

Premier Scénario:La

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 949
Date: Tue, 04 Jun 2013 02:59:35 GMT

Cela implique que le RESTE de l'API n'existe pas dans l'URL que vous devez fournir.

Cause:

  • Vous pourriez avoir une faute de frappe dans votre demande (croyez-moi, cela peut arriver)!
  • Il se peut que votre configuration spring n'est pas droit. Si c'est le cas, il a besoin de plus de creuser dans ce qui a mal tourné, mais j'ai fourni quelques actions que vous devez faire avant de commencer votre plus sophistiqué de l'enquête.

Actions:

Après vous être assuré que tout est fait à la perfection droit et rien de ce qui est erroné avec votre Configuration, ni vous URL: - Exécuter une maven propre. - D'annuler le déploiement de votre application web ou tout simplement le supprimer. - Redéployer l'application web - Assurez-vous d'utiliser une seule version de Printemps dans votre maven/gradle

Scénario Deux:

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 968
Date: Tue, 04 Jun 2013 03:08:05 GMT
Connection: close

La seule raison derrière cela est le fait que votre demande n'est pas formaté correctement. Si vous extrayez le détail curl réponse, vous devriez être capable de voir "La requête envoyée par le client est syntaxiquement incorrect.".

Cause:

Votre format JSON n'est pas droit ou qu'il vous manque un paramètre obligatoire pour objet JAVA.

Actions:

Assurez-vous de fournir de l'objet JSON dans le bon format et avec le bon nombre de paramètres. Nullable propriétés ne sont pas obligatoires mais vous n'avez pas à fournir des données pour tous les NotNullable propriétés. Il est TRÈS important de se rappeler que le Printemps est à l'aide de Java réflexion pour transformer la vôtre fichier JSON dans des objets Java, qu'est-ce que cela signifie? cela signifie que les variables et les noms de méthodes sont Sensibles à la casse. Si votre fichier JSON est l'envoi de la variable "nom d'utilisateur", que votre correspondant variable en Java objet DOIT également être nommé "nom d'utilisateur". Si vous avez des getters et setters, ils ont aussi de suivre la même règle. getUserName et setUserName pour correspondre à notre exemple précédent.

Senario Trois:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT

Cause:

Le Json type de support n'est pas pris en charge par votre service web. Cela pourrait être dû à votre annotation de ne pas spécifier le type de support ou vous ne spécifiez pas le type de média Curl poste de commandement.

Actions:

Vérifiez votre message convertisseur est mis en place correctement et assurez-vous que le service web d'annotation correspond à l'exemple ci-dessus. Si ceux-ci étaient beaux, assurez-vous de spécifier le type de contenu dans votre Curl requête post.

Le json type de support n'est pas pris en charge par votre service web.

Senario N(!):

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
Content-Type: application/json;charset=UTF-8 
Transfer-Encoding: chunked 
Date: Tue, 04 Jun 2013 03:06:16 GMT 

Félicitations à l'utilisateur est en fait de l'envoyer à vos côté serveur API REST.

Pour plus de détails sur la façon de configurer votre printemps la caisse de l'spring mvc guide.

Related posts et des questions

Cette FAQ n'a pas été possible si elle n'était pas pour toutes les personnes qui ont fourni les postes suivants et des questions (cette liste élargir si je viens à travers utiles related posts/questions):

  1. Quelle est la correcte JSON type de contenu?
  2. Spring 3.0 prise de réponse JSON à l'aide de jackson message convertisseur
  3. Comment publier des données JSON avec Curl à partir de la Borne/ligne de commande pour Tester Printemps RESTE?
  4. Affichage JSON à l'API REST
  5. https://github.com/geowarin/spring-mvc-examples
  6. Comment publier JSON en PHP avec curl
  7. Printemps de REPOS | MappingJacksonHttpMessageConverter produit invalid JSON
  8. https://github.com/eugenp/REST
  9. Web Spring MVC - valider la demande individuelle params
  10. Comment publier des données JSON avec Curl à partir de la Borne/ligne de commande pour Tester Printemps RESTE?
  11. Comment voulez-vous retourner un objet JSON à partir d'une Servlet Java
  12. Quel type MIME si JSON est retourné par une API REST?

1voto

Smoky Points 1204

Doit être bon de remarquer qu'un haricot classe ne peut PAS être traitée si elle a 2 ou plus setter pour un champ sans @JsonIgnore sur option. Printemps/Jackson jeter HttpMediaTypeNotSupportedException et de statut http 415 non pris en charge Type de Média.

Exemple :

@JsonGetter
public String getStatus() {
    return this.status;
}

@JsonSetter
public void setStatus(String status) {
    this.status = status;
}

@JsonIgnore
public void setStatus(StatusEnum status) {
    if (status == null) {
        throw new NullPointerException();
    }

    this.status = status.toString();
}

Mise à jour : Nous avons également spécifier @JsonGetter et @JsonSetter dans ce cas, de ne pas avoir de problèmes lorsqu'ils sont utilisés comme type de retour.

Juste testé avec le Printemps, 3.2.2 et Jackson 2.2. Il fonctionne très bien en tant que paramètre (@RequestBody) et/ou de type de retour (@ResponseBody).

Mise à jour 2 :

Si @JsonGetter et @JsonSetter sont spécifiés, @JsonIgnore ne semble pas être nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X