Spring MVCがjsonタイプのリクエストを処理し、Json形式を返すいくつかの方法

Spring MVCがjsonタイプのリクエストを処理し、Json形式を返すいくつかの方法

1つ、@ RequestBodyアノテーション

これは、クライアント(モバイルデバイス、ブラウザーなど)から送信されたjsonデータを解析し、エンティティクラスにカプセル化するのに役立ちます。
一般的に使用されるhttpリクエストのMIMEタイプは、application / json、text / html、text / xml、image / jpegなどで、固定フォーマットに対応するContent-Typeタイプです。
Webページのform要素の構文で、EncTypeは送信されたデータの形式を示します。Enctype属性を使用して、データをサーバーに送り返すときにブラウザーが使用するエンコードタイプを指定します。
例えば:

  • application / x-www-form-urlencoded:フォームデータは名前と値のペアとしてエンコードされます。これはデフォルトの(標準の)エンコード形式です。フォームのメソッドがgetの場合、ブラウザーはx-www-form-urlencodedのエンコード方法を使用して、フォームデータを文字列(name1 = value1&name2 = value2 ...)に変換し、この文字列を後ろに追加します。 URLのを?で分割し、この新しいURLをロードします。
  • multipart / form-data:フォームデータはメッセージとしてエンコードされます。ページ上の各コントロールはメッセージの一部に対応します。これは通常、ファイルをアップロードするときに使用されます。アクションが投稿されると、ブラウザはフォームデータをhttp本文にカプセル化し、サーバーに送信します。type = fileコントロールがない場合は、デフォルトのapplication / x-www-form-urlencodedを使用します。ただし、type = fileがある場合は、multipart / form-dataが使用されます。ブラウザはフォーム全体をコントロールの単位に分割し、Content-Disposition(フォームデータまたはファイル)、Content-Type(デフォルトのテキスト/プレーン)、名前(コントロール名)、およびその他の情報を各部分に追加し、セパレーター(境界)。
  • text / plain:フォームデータはプレーンテキストの形式でエンコードされます。プレーンテキストには、フォームのタイプに含まれていないコントロールやフォーマット文字は含まれていません。
    ポイントはここにあります~~~
    @ ReqeustBody:これは、
    content-typeがデフォルトのapplication / x-www-form-urlcodedエンコーディングではないコンテンツ(application / jsonやapplication / xmlなど)を処理するためによく使用されます。多くの場合、アプリケーションの/ jsonタイプを処理するために使用されます。
    注:@requestBodyは、JSONオブジェクトではなく、フロントエンドからjson文字列を受信します。httpプロトコルでは、文字列のみを送信できます。オブジェクトは、フロントエンドまたはバックエンド言語でのみ存在できるため、フロント-endJsonオブジェクトはjavascriptを使用する必要がありますjson文字列に変換するJSON.stringify()メソッドを提供します。
    さらに、JQueryのajaxを使用する場合、デフォルトのコンテンツタイプタイプはapplication / x-www-form-urlcodedです。
    JQueryajaxコード例
// Jquery Ajax请求
$.ajax({
    
    
    url : "doindex.action",
    type : "POST",
    contentType : "application/json;charset=UTF-8",
    data :JSON.stringify(json),
    dataType : "json",
    success : function(data) {
    
    
    }
});

ajaxのcontentType: "application / json; charset = UTF-8"、charset = UTF-8を書き込む必要があることに注意してください。そうしないと、バックエンドで文字が文字化けしやすくなり、tomcatのデフォルトの文字セットはutfではありません。 -8
。@ RequestBodyアノテーションは、前の段落で渡されたjson文字列を読み取るためにendメソッドの署名で使用されます。例を参照してください

@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;
    }

メソッド本体の特定のコードの意味に関係なく、フロントエンドからのjson文字列パラメーター情報は@RequestBody(required = true)でマークされたMap <String、Object>マップタイプに自動的に入力されます。これはどのように行われますか?
Springは、MappingJackson2HttpMessageConverter、StringHttpMessageConverterなど、多くのHttpMessageConverterを構築してくれました。主に@RequestBodyおよび@ResponsetBodyと協力します。
HttpMessageConverterインターフェースは、Spring 3.0で新しく追加されたインターフェースであり、1は要求情報をオブジェクト(タイプT)に変換し、2はオブジェクト(タイプT)を応答情報として出力します。
インターフェイスコードを見てください

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;
}

上記のインターフェースコードから、コンバーターはリクエスト情報を変換したり、レスポンス情報を自動的に変換したりできることがわかります。したがって、前のajaxリクエストの例に基づいて、バックエンドコードの受信方法は次のようになります。

  //以下三种方法头都可以接收前段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)

注:上記はSpringMVCデフォルトコンバーターを使用するためのものです。springmvc構成ファイルで他のコンバーターを指定した場合、指定したコンバーター機能によっては、上記の自動カプセル化が実現できる保証はありません。

2、@ ResponseBodyアノテーション

Controllerメソッドによって返されたオブジェクトをjson、xmlなどのHttpMessageConverterインターフェイスを介して指定された形式のデータに変換し、Responseを介してクライアントに応答するために使用されます。
注:文字列を渡す必要はありません対応するjavaクラスがある場合、SpringMVCはそれを要件を満たすデータ形式(json / xml)に自動的に変換するのに役立ちます。
実際の測定後に前のセクションの対応するタイプのjsonに返すことができるいくつかのメソッドを次に示します

1.次の方法の前提条件の構成

web.xmlで、DispatcherServletリクエストインターセプトで* .actionのインターセプトを構成します。これは、jsonリターンの処理に使用されます。追加されていない場合、構成されたビューリゾルバーがデフォルトで呼び出されて解決されます。解決に失敗した場合は、エラー406が報告されるため、新しいマッピングタイプを追加した後、jsonの戻り値は特別に処理されます。

<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>

リクエストの傍受が追加されたとき

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

jsonを返す必要がある以前のすべてのリクエストには、アクションの接尾辞を付ける必要があります。もちろん、アクションは、doなどの任意の名前に変更できます。

2.json形式を返すいくつかの@ResponseBody

springmvcでjson形式を処理するには、いくつかのjarパッケージのサポートが必要なため、最初に次の依存関係を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>
  • MappingJackson2JsonViewビューを使用してjsonspringmvc
    構成ファイル(**-servlet.xmlを返し、 JSPビューパーサーを
    構成します; springmvc構成ファイルで構成します(**-servlet.xml<mvc:annotation-driven/>;
    メソッドは@ResponseBodyアノテーションを使用します;
    返されたModelAndViewでMappingJackson2JsonViewビューを構成し、jsonエンティティインスタンス、コレクションを返しますまたは、ModelAndViewに直接コピーされたマップタイプ。ここでは次の点に注意してください。返されるエンティティインスタンス、コレクション、またはマップタイプがModelAndViewに追加され、名前が指定されている場合、返されるjson名は指定された名前です(名前がない場合)。が指定されている場合、返されるjson Nameは、エンティティインスタンス、コレクション、またはマップタイプ名の小文字の名前です。例を見る
  @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;
    }

フロントエンドによって要求されたパラメーターはjson文字列{"username":"测试","password":"123456fg"}であり、メソッドの@RequestBody文字列型パラメーターusernameによって取得された挿入値は、フロントエンドから渡されたjson文字列です。
getDo1メソッドの実行後に前のステージに返される応答出力は次のとおりです。

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

フロントエンドへのjson出力は、custインスタンスの小文字のクラス名をjson文字列のキーとして出力し、日付createtimeはタイムスタンプタイプに従って出力されることがわかります。時間出力をフォーマットする場合は、com.fasterxml.jackson.databind.ObjectMapperクラスを使用する必要がありますこの時点で、上記のコードを次のように変更します。

@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;
    }

リクエストパラメータは変更されません。対応する結果は次のとおりです。

{
    
    "customer":{
    
    "sysId":null,"2019-12-23 15:10:41","lcname":"马雷"}}
  • オブジェクトタイプを直接返し、json形式の
    springmvc構成ファイル(**-servlet.xml)を出力して、JSPのビューパーサーを
    構成します。springmvc構成ファイルで構成します(**-servlet.xml<mvc:annotation-driven/>;
    メソッド使用@ResponseBodyアノテーション;
    上記のメソッド:
 @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は、メソッドまたはメソッドシグネチャでマークできます。
フロントエンドによって要求されるパラメーターは引き続きjson文字列{"username":"测试","password":"123456fg"}です。次の概要では、フロントエンドの各要求パラメーターはこの文字列であるため、繰り返しません。別々に。
フロントエンドに対応する出力結果は次のとおりです。

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

createtimeはまだ出力タイムスタンプであり、日付と時刻の形式に変換する良い方法がないことがわかります。
注:上記の2つの方法の違い
1.日付をフォーマットするには、最初のメソッドのみを使用できます
。2。出力jsonに{"key": "value"、 "key": "value"}フォーマットが必要な場合、最初の2つのタイプ、または最初のタイプと2番目のタイプはマップカプセル化を使用できます。

  • MappingJackson2HttpMessageConverterはjson出力を実装します。
    最初に、springmvc構成ファイルで**-servlet.xml次のコードを構成します(
   <!-- 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>

上記のコードはmvc:annotation-drivenを置き換えます。2
番目のステップは、メソッド内またはメソッド上で@ResponseBodyアノテーションを使用することです。コードを参照してください。

@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;
    }

フロントエンドはapplication / x-www-form-urlcoded形式を使用し、URLはtest4.action?username = T试&password = 123456fgです。
応答出力は

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

フロントエンドはapplication / json; charset = UTF-8形式を使用することもでき、バックエンドのメソッドは次のとおりです。

@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;
    }

ここで強調したいのは、@ RequestBody署名を使用する場合、マップをカプセル化してフロントエンドからjson文字列を受信するか、エンティティクラスを使用してフロントエンドからjson文字列を受信することができます。文字列を直接使用することはできません。フロントエンドを受信する文字列。jsonを使用すると、400エラーが報告されます。さらに、エンティティクラスを使用してフロントエンド文字列のjson文字列を受信すると、エンティティクラスの属性が少なくなります。渡された文字列の属性よりも、400エラーも報告されます。
このメソッドを使用してjsonを出力する利点は、日付をフォーマットできることです。

さらに、ツールを紹介します。posmanは、デバッグの要求をシミュレートするために使用されます。これは特に優れています。
ダウンロードアドレス、
使用方法、win7パッチの2つの参照アドレスを指定してください。

おすすめ

転載: blog.csdn.net/u011930054/article/details/103663772