Plusieurs façons dont Spring MVC gère les demandes de type Json et renvoie le format Json

Plusieurs façons dont Spring MVC gère les demandes de type Json et renvoie le format Json

Une, annotation @RequestBody

Il peut nous aider à analyser les données json envoyées par le client (appareil mobile, navigateur, etc.) et à les encapsuler dans la classe d'entité.
Les types MIME de requête http couramment utilisés sont application / json, text / html, text / xml, image / jpeg, etc., qui sont des types Content-Type correspondant à des formats fixes.
Dans la syntaxe de l'élément de formulaire de la page Web, EncType indique le format des données soumises. Utilisez l'attribut Enctype pour spécifier le type de codage utilisé par le navigateur lors du renvoi des données au serveur.
Par exemple:

  • application / x-www-form-urlencoded: les données du formulaire sont codées sous forme de paires nom / valeur. Il s'agit du format d'encodage par défaut (standard). Lorsque la méthode du formulaire est get, le navigateur utilise la méthode de codage de x-www-form-urlencoded pour convertir les données du formulaire en une chaîne (nom1 = valeur1 & nom2 = valeur2 ...), puis ajoute cette chaîne à l'arrière de l'url et divisez-la avec?, Chargez cette nouvelle URL.
  • multipart / form-data: les données du formulaire sont encodées sous forme de message. Chaque contrôle de la page correspond à une partie du message. Ceci est généralement utilisé lors du téléchargement de fichiers. Lorsque l'action est postée, le navigateur encapsule les données du formulaire dans le corps http et les envoie au serveur. S'il n'y a pas de contrôle type = file, utilisez l'application par défaut / x-www-form-urlencoded. Mais s'il y a type = file, multipart / form-data sera utilisé. Le navigateur divisera le formulaire entier en unités de contrôles, et ajoutera Content-Disposition (données de formulaire ou fichier), Content-Type (texte par défaut / plain), nom (nom du contrôle) et d'autres informations à chaque partie, et ajoutera le séparateur (frontière).
  • text / plain: les données du formulaire sont codées sous forme de texte brut, qui ne contient aucun contrôle ou caractère de format, qui ne sont pas inclus dans le type de formulaire.
    Le point est ici ~~~
    @ReqeustBody: Il est
    souvent utilisé pour traiter le contenu dont le type de contenu n'est pas le codage par défaut application / x-www-form-urlcoded , tel que application / json ou application / xml, etc., qui sont souvent utilisés pour traiter le type application / json.
    Remarque: @requestBody reçoit la chaîne json du front-end, pas de l'objet JSON. Dans le protocole http, seule la chaîne peut être transmise. L'objet ne peut exister que dans le langage front-end ou back-end, donc le front -end L'objet Json doit utiliser javascript Fournissez la méthode JSON.stringify () à convertir en chaîne json.
    De plus, lorsque vous utilisez ajax de JQuery, le type de type de contenu par défaut est application / x-www-form-urlcoded.
    Un exemple de code JQuery ajax
// Jquery Ajax请求
$.ajax({
    
    
    url : "doindex.action",
    type : "POST",
    contentType : "application/json;charset=UTF-8",
    data :JSON.stringify(json),
    dataType : "json",
    success : function(data) {
    
    
    }
});

Notez que le contentType en ajax: "application / json; charset = UTF-8", charset = UTF-8 doit y être écrit, sinon le backend est sujet aux caractères chinois déformés et le jeu de caractères par défaut de tomcat n'est pas utf -8
. L'annotation @RequestBody est utilisée dans la signature de la méthode de fin pour lire la chaîne json passée dans le paragraphe précédent, voir un exemple

@RequestMapping("/doindex.action")
    public @ResponseBody Customer getPages(@RequestBody(required=true) Map<String,Object> map , HttpServletRequest request)throws Exception{
    
    
        Customer cust=new Customer();
        cust.setLcname("马雷");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        //mv.addObject(cust);
        //Map<String,Object> map=new HashMap();
        //map.put("cust",cust);
        ObjectMapper om=new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        //ModelAndView mv=new ModelAndView(new MappingJackson2JsonView(om),cust);
        return cust;
    }

Quelle que soit la signification du code spécifique dans le corps de la méthode, les informations de paramètre de chaîne json du frontend sont automatiquement remplies dans le type de carte Map <String, Object> marqué par @RequestBody (required = true). Comment procéder?
Spring a construit beaucoup de HttpMessageConverter pour nous, par exemple, MappingJackson2HttpMessageConverter, StringHttpMessageConverter, etc. Principalement pour coopérer avec @RequestBody et @ResponsetBody.
L'interface HttpMessageConverter est une interface nouvellement ajoutée dans Spring 3.0, qui est responsable de 1, la conversion des informations de demande en un objet (type T), et 2, la sortie de l'objet (type T) en tant qu'informations de réponse.
Jetez un œil au code de l'interface

public interface HttpMessageConverter<T> {
    
    
    //指定转换器 可以读取的对象类型,即转换器是否可将请求信息转换为clazz类型的对象,同时指定支持 MIME 类型(text/html,applaiction/json等)
    boolean canRead(Class<?> var1, MediaType var2);
    //指定转换器 是否可将 clazz类型的对象写到响应流中,响应流支持的媒体类型在MediaType 中定义。–LIst getSupportMediaTypes():该转换器支持的媒体类型
    boolean canWrite(Class<?> var1, MediaType var2);
	
    List<MediaType> getSupportedMediaTypes();
	//将请求信息流转换为 T 类型的对象
    T read(Class<? extends T> var1, HttpInputMessage var2) throws IOException, HttpMessageNotReadableException;
     //将T类型的对象写到响应流中,同时指定相应的媒体类型为contentType
    void write(T var1, MediaType var2, HttpOutputMessage var3) throws IOException, HttpMessageNotWritableException;
}

À partir du code d'interface ci-dessus, on peut voir que le convertisseur peut convertir les informations de demande, ou convertir automatiquement les informations de réponse, donc sur la base de l'exemple de demande ajax précédent, la méthode de réception de code back-end peut être

  //以下三种方法头都可以接收前段ajax传入的非application/x-www-form-urlcoded类型信息
 //将传入的json参数自动封装到map里,参数名成是key,参数值时value
 public @ResponseBody Customer getPages(@RequestBody(required=true) Map<String,Object> map , HttpServletRequest request)
 //将传入的json字符串直接复制给username字段
 public @ResponseBody Customer getPages(@RequestBody(required=true) String username, HttpServletRequest request)
 //将传入的json字符串中每个字段的值赋给user对象实例对应名称的属性
 public @ResponseBody Customer getPages(@RequestBody(required=true) User user , HttpServletRequest request)

Remarque: Ce qui précède consiste à utiliser le convertisseur par défaut de SpringMVC. Si vous spécifiez d'autres convertisseurs dans le fichier de configuration springmvc, il n'y a aucune garantie que l'encapsulation automatique ci-dessus puisse être réalisée, selon la fonction de convertisseur spécifiée.

Deux, annotation @ResponseBody

Utilisé pour convertir l'objet renvoyé par la méthode Controller en données au format spécifié via l'interface HttpMessageConverter, telle que json, xml, etc., et répondre au client via la réponse.
Remarque: Il n'est pas nécessaire de transmettre la chaîne, s'il existe une classe java correspondante, SpringMVC aidera automatiquement à la convertir en un format de données qui répond aux exigences (json / xml).
Voici plusieurs méthodes qui peuvent être renvoyées au type de json correspondant dans la section précédente après la mesure réelle:

1. Configuration requise pour les méthodes suivantes

Dans web.xml, configurez une interception de * .action dans l'interception de demande DispatcherServlet, qui est utilisée pour traiter le retour json. S'il n'est pas ajouté, le résolveur de vue configuré sera appelé par défaut pour le résoudre. Si la résolution échoue, une erreur 406. Ainsi, après l'ajout d'un nouveau type de mappage, les retours json sont traités spécialement.

<servlet-mapping>
  <servlet-name>miniappservice</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 解决*.html后缀请求,无法返回json -->
<servlet-mapping>
  <servlet-name>miniappservice</servlet-name>
  <url-pattern>*.action</url-pattern>
 </servlet-mapping>

Lorsque l'interception de la demande est ajoutée

<servlet-mapping>
  <servlet-name>miniappservice</servlet-name>
  <url-pattern>*.action</url-pattern>
 </servlet-mapping>

Toutes les demandes précédentes qui doivent renvoyer json doivent porter le suffixe action. Bien entendu, l'action peut être remplacée par n'importe quel nom tel que do

2. Plusieurs @ResponseBody qui renvoient le format json

Étant donné que le traitement du format json dans springmvc nécessite la prise en charge de certains packages jar, ajoutez d'abord les dépendances suivantes à la liste pom:

    <!--com.fasterxml.jackson.databind.ObjectMapper servlet配置需要-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.10.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.10.1</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.10.1</version>
    </dependency>
  • Utilisez la vue MappingJackson2JsonView pour renvoyer le
    fichier de configuration json springmvc ( **-servlet.xml) pour configurer l'analyseur de vue JSP;
    configurer dans le fichier de configuration springmvc ( **-servlet.xml) <mvc:annotation-driven/>;
    méthode utiliser des @ResponseBodyannotations;
    configurer la vue MappingJackson2JsonView dans le ModelAndView renvoyé et renvoyer l'instance d'entité json, Collection ou le type de carte directement copié dans ModelAndView, ici pour faire attention à ce qui suit, si l'instance d'entité, la collection ou le type de carte à retourner est ajouté à ModelAndView et que le nom est spécifié, le nom json renvoyé est le nom spécifié, si aucun nom est spécifié, le json renvoyé Le nom est le nom en minuscules de l'instance d'entité, de la collection ou du nom du type de carte. Voir un exemple
  @RequestMapping("/test1.action")
    @ResponseBody
    public ModelAndView getDo1(@RequestBody(required=true) String username , HttpServletRequest request){
    
    
        Customer cust=new Customer();
        cust.setLcname("测试");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        ModelAndView mv=new ModelAndView(new MappingJackson2JsonView());
        mv.addObject(cust);
        return mv;
    }

Le paramètre demandé par le frontal est une chaîne json {"username":"测试","password":"123456fg"}, et la valeur injectée obtenue par le paramètre de type de chaîne @RequestBody nom_utilisateur dans la méthode est la chaîne json transmise depuis le frontal.
La sortie de réponse renvoyée à l'étape précédente après l'exécution de la méthode getDo1 est:

{
    
    "customer":{
    
    "sysId":null,"createtime":1577084421101,,"lcname":"马雷"}}

On peut voir que la sortie json vers le frontal génère le nom de classe en minuscules de l'instance cust comme clé de la chaîne json, et la date createtime est sortie en fonction du type d'horodatage. Si vous souhaitez formater la sortie de l'heure, vous devez utiliser la com.fasterxml.jackson.databind.ObjectMapperclasse À ce stade, modifiez le code ci-dessus comme suit:

@RequestMapping("/test2.action")
    @ResponseBody
    public ModelAndView getDo2(@RequestBody(required=true) String username , HttpServletRequest request){
    
    
        Customer cust=new Customer();
        cust.setLcname("马雷");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        //引入格式化
        ObjectMapper om=new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        ModelAndView mv=new ModelAndView(new MappingJackson2JsonView(om));
        mv.addObject(cust);
        return mv;
    }

Les paramètres de la requête restent inchangés et les résultats correspondants sont les suivants:

{
    
    "customer":{
    
    "sysId":null,"2019-12-23 15:10:41","lcname":"马雷"}}
  • Renvoyez directement le type d'objet et
    sortez le fichier de configuration springmvc au format json ( **-servlet.xml) pour configurer l'analyseur de vue de JSP;
    configurer dans le fichier de configuration springmvc ( **-servlet.xml) <mvc:annotation-driven/>;
    méthode utiliser l' @ResponseBodyannotation;
    méthode ci-dessus:
 @RequestMapping("/test3.action")
    public @ResponseBody Map<String,Object> getDo3(@RequestBody(required=true) String username , HttpServletRequest request){
    
    
        Customer cust=new Customer();
        cust.setLcname("测试");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        Map<String,Object> map=new HashMap<>();
        map.put("customer",cust);
        return map;
    }

@ResponseBody peut être marqué sur la méthode ou sur la signature de la méthode;
les paramètres demandés par le front-end sont toujours des chaînes json {"username":"测试","password":"123456fg"}. Dans l'introduction qui suit, chaque paramètre de requête du front-end est cette chaîne, donc je ne les répéterai pas séparément.
Le résultat de sortie correspondant au frontal est:

{
    
    "customer":{
    
    "sysId":null,"createtime":1577085315542,"lcname":"测试"}}

On peut voir que createtime est toujours l'horodatage de sortie, et il n'y a pas de bon moyen de le convertir en un format de date et d'heure.
Remarque: La différence entre les deux méthodes ci-dessus
1. Pour formater la date, seule la première peut être utilisée;
2. Si la sortie json a besoin du format {"key": "value", "key": "value"}, vous pouvez utiliser les deux premiers types ou le premier type et le second type utilisent l'encapsulation de carte;

  • MappingJackson2HttpMessageConverter implémente la sortie json.
    Commencez par **-servlet.xmlconfigurer le code suivant dans le fichier de configuration springmvc ( )
   <!-- mvc:annotation-driven:使用mvc注解,解决406同时解决时间问题 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

Le code ci-dessus remplace mvc: basé sur les annotations; la
deuxième étape consiste à utiliser l'annotation @ResponseBody dans ou sur la méthode, voir le code

@RequestMapping("/test4.action")
    public @ResponseBody Customer getDo4(String username,String password, HttpServletRequest request){
    
    
        Customer cust=new Customer();
        cust.setLcname("测试");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        return cust;
    }

Le frontal utilise le format application / x-www-form-urlcoded, et l'url est test4.action? Username = 测试 & password = 123456fg; le
résultat de la réponse est

{
    
    
    "sysId": null,
    "createtime": "2019-12-23 16:08:17",
    "lcname": "测试"
}

Le front-end peut également utiliser le format application / json; charset = UTF-8, et la méthode d'arrière-plan est la suivante:

@RequestMapping("/test4.action")
    public @ResponseBody List<Customer> getDo4(@RequestBody(required=true) Map<String,Object> map1 , HttpServletRequest request){
    
    
        Customer cust=new Customer();
        cust.setLcname("测试");
        cust.setCreatetime(new Timestamp(System.currentTimeMillis()));
        List<Customer> map=new ArrayList<>();
        map.add(cust);
        return map;
    }

Je tiens à souligner ici que lorsque vous utilisez la signature @RequestBody, vous pouvez encapsuler la carte pour recevoir la chaîne json du front-end, ou utiliser la classe d'entité pour recevoir la chaîne json du front-end. Vous ne pouvez pas utiliser directement la chaîne string pour recevoir le front-end. Si le json est utilisé, il signale une erreur 400. De plus, si la classe d'entité est utilisée pour recevoir la chaîne json de la chaîne front-end, l'attribut de la classe d'entité est inférieur que l'attribut de la chaîne passée, l'erreur 400 sera également signalée.
L'avantage d'utiliser cette méthode pour générer json, vous pouvez formater la date;

De plus, j'introduis un outil, posman est utilisé pour simuler des requêtes de débogage, ce qui est particulièrement bon. Donnez deux adresses de référence:
adresse de téléchargement,
mode d'emploi,
patch win7

Je suppose que tu aimes

Origine blog.csdn.net/u011930054/article/details/103663772
conseillé
Classement