Printemps 4.x / 3.x (Web MVC), API REST et JSON2 requêtes Post, comment l'obtenir droite, une fois pour toutes?

avant d'entrer dans les détails, je sais qu'il y a eu beaucoup de conversations et de questions connexes sur Stackoverflow. Tous ces types d'aide moi de différentes façons donc j'ai pensé que j'ai mis mes conclusions tous ensemble comme une FAQ organisée unique pour résumer mes conclusions.

Des Concepts Liés À L'

vous les connaissez sûrement, mais je les écris rapidement. N'hésitez pas à éditer au cas où je manquerais quelque chose.

HTTP POST Demande:

une requête post est utilisée lorsque vous êtes prêt à envoyer un objet vers un service web ou une application côté serveur.

Sérialisation:

est le processus pour obtenir l'objet à partir de votre navigateur web à travers votre application côté serveur. Un appel Ajax jQuery ou une requête Curl post peuvent être utilisés.

Sérialisation des protocoles:

les plus populaires ces jours sont JSON et XML. Le XML est de moins en moins populaire car les objets XML sérialisés sont de plus en plus gros en raison de la nature du balisage XML. Dans cette FAQ le thème principal est JSON2 sérialisation.

le Printemps:

cadre de ressort et son annotation puissante permet d'exposer le service web d'une manière efficace. Il ya beaucoup de différentes bibliothèques au Printemps. Celui qui est notre objectif ici est printemps Web MVC .

Curl vs JQuery:

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

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

dans les cas où vous avez un service web qui ne dépend pas de votre modèle Java EE, @RequestBody doit être utilisé. Si vous utilisez le model et que votre objet JSON est ajouté au model, vous pouvez accéder à l'objet via @ModelAttribute. Seulement dans les cas où votre requête est une requête GET ou une combinaison GET et POST, vous devrez utiliser @RequestParam/@PathVariable.

@RequestBody vs @ResposeBody:

comme vous pouvez le voir du nom il est aussi simple que cela, vous avez seulement besoin de la @Responsabilebody si vous envoyez une réponse le client après que la méthode côté serveur a traité la requête.

RequestMappingHandlerAdapter vs AnnotationMethodHandlerAdapter:

RequestMappingHandlerAdapter est le nouveau gestionnaire de mapping pour la charpente de ressort qui a remplacé AnnotationMethodHandlerAdapter depuis le printemps 3.1. Si votre configuration existante est toujours dans AnnotationMethodHandlerAdapter, vous pourriez trouver ce post utile. La configuration fournie dans mon post vous donnera une idée sur la façon de mettre en place le RequestMappingHandlerAdapter.

Setup

vous aurez besoin de configurer un convertisseur de messages. C'est ainsi que votre corps de message JSON sérialisé est converti en un objet java local du côté de votre serveur.

Configuration de base de ici . Les convertisseurs étaient MarshallingHttpMessageConverter et CastorMarshaller dans la configuration de base échantillon , je les ai remplacés par MappingJackson2HttpMessageConverter et MappingJacksonHttpMessageConverter.

où placer la configuration

la façon dont mon projet est configuré, j'ai deux fichiers de configuration:

  • contexte de L'Application XML: L'un est le fichier XML de contexte d'application où votre fève sessionFactory, fève dataSource,etc. sont situés.
  • Servlet de répartiteur MVC XML: C'est ici que vous avez votre point de vue de résolveur et importez votre contexte D'application XML.

hadlerAdapter bean doit être localisé dans le fichier XML du répartiteur MVC.

<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 convertisseurs de messages. ici, j'ai créé un JSON normal ainsi qu'un convertisseur de messages JSON 2. Ref et le format normal bean dans le fichier XML ont été utilisés (personnellement, je préfère la balise ref comme son plus proche).

REST API

voici un contrôleur d'échantillon qui expose l'API REST.

le contrôleur

c'est ici que votre API REST pour une requête HTTP 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 Post call

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

articles connexes et questions

cette FAQ n'a pas été possible si ce n'était pas pour toutes les personnes qui ont fourni les messages et les questions suivantes (cette liste s'élargira si je tombe sur des messages/questions connexes utiles):

  1. Qu'est-ce que le correct type de contenu JSON?
  2. Printemps 3.0 prise de réponse JSON à l'aide de jackson message "convertisseur de 1519220920"
  3. Comment publier des données JSON avec Curl à partir de Terminal / ligne de commande pour tester le ressort de repos?
  4. Affichage JSON à l'API REST
  5. https://github.com/geowarin/spring-mvc-examples
  6. Comment publier JSON en PHP avec curl
  7. Spring REST | MappingJacksonHttpMessageConverter produces 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 de repos?
40
demandé sur Community 2013-06-04 08:18:19
la source

2 ответов

CURL Post call

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

Différents Scénarios D'Erreur:

ici, j'explore différentes erreurs que vous pourriez rencontrer après que vous avez fait un appel bouclé et ce qui pourrait avoir mal tourné.

Scénario Un:

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 L'API REST n'existe pas dans l'URL que vous avez fourni.

Cause:
  • vous pourriez avoir une faute de frappe dans votre demande (croyez-moi, cela peut arriver)!
  • il se peut que votre configuration de ressort ne soit pas correcte. Si c'est le cas, il faut creuser davantage sur ce qui a réellement mal tourné, mais j'ai fourni quelques actions initiales que vous devez faire avant de commencer votre enquête plus sophistiquée.
Action:

après vous être assuré que tout se passe parfaitement bien et que rien ne va mal avec votre Configuration ni votre URL: - Exécuter un maven propre. - Désactivez votre application web ou supprimez-la. - Redéployer l'application web - Assurez-vous d'utiliser une seule version de ressort 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 que votre demande n'est pas formatée correctement. Si vous vérifiez la réponse curl détaillée, vous devriez être en mesure de voir "la demande envoyée par le client était syntaxiquement incorrecte.".

Cause:

soit votre format JSON n'est pas correct ou il vous manque un paramètre obligatoire pour L'objet JAVA.

Action:

assurez-vous de fournir l'objet JSON dans le format correct et avec le bon nombre de paramètres. Les propriétés nullables ne sont pas obligatoires, mais vous devez fournir des données pour toutes les propriétés nullables. Il est très important de se rappeler que Spring utilise Java reflection pour transformer votre fichier JSON en objets Java, qu'est-ce que cela signifie? cela signifie que la variable et la méthode les noms sont sensibles à la casse. Si votre fichier JSON envoie la variable "userName", la variable correspondante dans votre objet Java doit aussi être nommée "userName". Si vous avez getters et setters, ils doivent aussi suivre la même règle. getUserName et setUserName correspondent à 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 type de média Json n'est pas supporté par votre service web. Cela pourrait être dû à votre annotation ne spécifiant pas le type de média ou vous ne spécifiez pas le type de média dans la commande Curl post.

Action:

vérifiez que votre convertisseur de messages est configuré correctement et assurez-vous que l'annotation du service web correspond à l'exemple ci-dessus. Si celles-ci étaient correctes, assurez-vous de spécifier le type de contenu dans votre requête Curl post.

le type de média json n'est pas supporté 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 envoyé à votre API REST côté serveur.

pour plus de détails sur la façon de configurer votre commande de ressort, consultez le guide MVC du ressort.

Related posts and questions ""

cette FAQ n'a pas été possible si ce n'était pas pour toutes les personnes qui ont fourni les messages et les questions suivantes (cette liste va s'étendre si je tombe sur des messages/questions connexes utiles):

  1. Qu'est-ce que le correct type de contenu JSON?
  2. Printemps 3.0 prise de réponse JSON à l'aide de jackson message "convertisseur de 1519540920"
  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. Spring REST | MappingJacksonHttpMessageConverter produces 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 Boucler du Terminal / ligne de commande pour tester le ressort de repos?
  11. Comment retourner un objet JSON d'un Servlet Java
  12. quel type MIME si JSON est retourné par une API REST?

11
répondu AmirHd 2017-05-23 15:16:56
la source

devrait être bon à noter qu'une classe de haricot peut pas être manipulé si elle a 2 ou plusieurs setter pour un champ sans @JsonIgnore sur les facultatifs. Spring / Jackson throw HttpMediaTypeNotSupportedException et http status 415 unsupported Media Type.

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 devons également préciser @JsonGetter et @JsonSetter dans ce cas, ne pas avoir des problèmes lorsqu'il est utilisé comme type de retour.

vient de le tester avec Spring 3.2.2 et Jackson 2.2. Il fonctionne très bien comme paramètre ( @RequestBody ) et / ou comme type de retour ( @ResponseBody ).

mise à jour 2:

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

1
répondu Ludovic Guillaume 2013-06-05 14:52:59
la source

Autres questions sur java json curl spring html-post