【SpringMVC】リクエストとレスポンス

1. PostMan ツールの使用

1. PostMan の概要

コードを記述した後、テストする場合は、ブラウザを開いてアドレスを直接入力してリクエストを送信するだけです。GETブラウザを使用して直接リクエストを送信することもできますが、POSTリクエストを送信したい場合はどうすればよいでしょうか?

投稿リクエストを送信する場合は、ページを用意してページ上にフォームフォームを用意する必要があり、テストが面倒になります。したがって、PostMan などのサードパーティ ツールを使用する必要があります。

  • PostMan は、Web ページをデバッグし、Web ページに対する HTTP リクエストを送信するための強力な Chrome プラグインです。

ここに画像の説明を挿入

  • 機能: インターフェイスのテストによく使用されます。

  • 特徴

    • 単純
    • 実用的
    • 美しい
    • 優しい

2.PostManのインストール

PostMan の公式ダウンロード Web サイト: PostMan は
ここに画像の説明を挿入
ダブルクリックするとPostman-win64-8.3.1-Setup.exe自動的にインストールされます。インストールが完了した後、登録が必要な場合は、プロンプトに従って登録できます。下部にテストをスキップするリンクがある場合は、登録できます。クリックして登録をスキップすることもできます

次のインターフェイスが表示されたら、インストールが成功したことを意味します。

ここに画像の説明を挿入

3. ポストマンの使用

1. WorkSpace ワークスペースを作成する

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

2. リクエストを送信する

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-X3sq1fXc-1682171003098)(assets/1630464489898.png)]
ここに画像の説明を挿入

3. 現在のリクエストを保存します

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-TTg9Rmas-1682171003099)(assets/1630464783034.png)]

注:最初のリクエストでは新しいディレクトリを作成する必要がありますが、後で新しいディレクトリを作成する必要はなく、作成済みのディレクトリに直接保存するだけです。

2. リクエストとレスポンス

導入ケースに関する知識の学習はすでに完了しており、次に SpringMVC に関する知識を体系的に学習する必要があります。前述したように、SpringMVC は Web 層のフレームワークです。主な機能はリクエストを受信し、受信することです。データ、応答結果、この章は SpringMVC を学習するためのものです集中内容としては、主に次の4つの部分について説明します。

  • リクエストマッピングパス
  • リクエストパラメータ
  • 日付型パラメータの受け渡し
  • レスポンスのjsonデータ

1. リクエストマッピングパスを設定する

1. 環境の準備

  • Web Maven プロジェクトを作成する

  • pom.xml は Spring 依存関係を追加します

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.itheima</groupId>
      <artifactId>springmvc_03_request_mapping</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.10.RELEASE</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
              <port>80</port>
              <path>/</path>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
    
  • 対応する構成クラスを作成する

    public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          
          
    
        protected Class<?>[] getServletConfigClasses() {
          
          
            return new Class[]{
          
          SpringMvcConfig.class};
        }
        protected String[] getServletMappings() {
          
          
            return new String[]{
          
          "/"};
        }
        protected Class<?>[] getRootConfigClasses() {
          
          
            return new Class[0];
        }
    }
    
    @Configuration
    @ComponentScan("com.itheima.controller")
    public class SpringMvcConfig {
          
          
    }
    
    
  • BookController と UserController を書く

    @Controller
    public class UserController {
          
          
    
        @RequestMapping("/save")
        @ResponseBody
        public String save(){
          
          
            System.out.println("user save ...");
            return "{'module':'user save'}";
        }
        
        @RequestMapping("/delete")
        @ResponseBody
        public String save(){
          
          
            System.out.println("user delete ...");
            return "{'module':'user delete'}";
        }
    }
    
    @Controller
    public class BookController {
          
          
    
        @RequestMapping("/save")
        @ResponseBody
        public String save(){
          
          
            System.out.println("book save ...");
            return "{'module':'book save'}";
        }
    }
    

最終的に作成されたプロジェクト構造は次のとおりです。

ここに画像の説明を挿入

環境を準備した後、Tomcat サーバーを起動すると、バックグラウンドでエラーが報告されます。

ここに画像の説明を挿入

それはエラー メッセージからわかります。

  • UserControllerにはsaveメソッドがあり、アクセスパスはhttp://localhost/save
  • BookControllerにもsaveメソッドがあり、アクセスパスはhttp://localhost/save
  • にアクセスする場合http://localhost/saved、UserController または BookController にアクセスしますか?

2. 問題分析

チームは複数人で開発しており、各人が異なるリクエストパスを設定しているのですが、競合の問題をどのように解決すればよいでしょうか?

解決策: モジュール名をさまざまなモジュールのリクエスト パス プレフィックスとして設定します。

Book モジュールを保存するには、そのアクセス パスを次のように設定します。http://localhost/book/save

ユーザーモジュールを保存するには、そのアクセスパスを次のように設定します。http://localhost/user/save

こうすることで、同じモジュール内で名前が競合するケースが少なくなります。

3. マッピングパスを設定する

ステップ 1: コントローラーを変更する
@Controller
public class UserController {
    
    

    @RequestMapping("/user/save")
    @ResponseBody
    public String save(){
    
    
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }
    
    @RequestMapping("/user/delete")
    @ResponseBody
    public String save(){
    
    
        System.out.println("user delete ...");
        return "{'module':'user delete'}";
    }
}

@Controller
public class BookController {
    
    

    @RequestMapping("/book/save")
    @ResponseBody
    public String save(){
    
    
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}

問題は解決しましたが、メソッドの前に各メソッドを変更する必要があるため、書くのが面倒で繰り返しコードが多く、後で /user を変更するとすべてのメソッドを変更する必要があり、結合度が高すぎます。

ステップ 2: パス構成を最適化する

最適化:

@Controller
@RequestMapping("/user")
public class UserController {
    
    

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    
    
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }
    
    @RequestMapping("/delete")
    @ResponseBody
    public String save(){
    
    
        System.out.println("user delete ...");
        return "{'module':'user delete'}";
    }
}

@Controller
@RequestMapping("/book")
public class BookController {
    
    

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    
    
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}

知らせ:

  • アノテーションがクラスとメソッドに追加されると@RequestMapping、フロントエンドがリクエストを送信するときに、アノテーションを追加して 2 つのアノテーションの値と照合してアクセスする必要があります。
  • @RequestMapping アノテーション値属性を追加するかどうかを選択/できます。

ちょっとした知識の拡張:

PostMan が文字が小さいと見栄えが悪いと判断する理由としては、ctrl+=調整方法を使用してctrl+-サイズを拡大または縮小することができます。

2. リクエストパラメータ

リクエストパスの設定後、ページ送信リクエストのアドレスがバックグラウンドのControllerクラスに設定されているパスと一致していればフロントエンドリクエストを受信できます リクエスト受信後、ページから渡されるパラメータを受け取る方法?

リクエスト パラメータの送受信はリクエスト メソッドに関連しており、現在一般的なリクエスト メソッドは次の 2 つです。

  • 得る
  • 役職

フロントエンドはさまざまなリクエストをどのように送信し、バックエンドはそれらをどのように受信するのでしょうか?

1. 環境の準備

  • Web Maven プロジェクトを作成する

  • pom.xml は Spring 依存関係を追加します

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.itheima</groupId>
      <artifactId>springmvc_03_request_mapping</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.10.RELEASE</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
              <port>80</port>
              <path>/</path>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
    
  • 対応する構成クラスを作成する

    public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          
          
    
        protected Class<?>[] getServletConfigClasses() {
          
          
            return new Class[]{
          
          SpringMvcConfig.class};
        }
        protected String[] getServletMappings() {
          
          
            return new String[]{
          
          "/"};
        }
        protected Class<?>[] getRootConfigClasses() {
          
          
            return new Class[0];
        }
    }
    
    @Configuration
    @ComponentScan("com.itheima.controller")
    public class SpringMvcConfig {
          
          
    }
    
    
  • ユーザーコントローラーの書き込み

    @Controller
    public class UserController {
          
          
    
        @RequestMapping("/commonParam")
        @ResponseBody
        public String commonParam(){
          
          
            return "{'module':'commonParam'}";
        }
    }
    
  • モデルクラス、ユーザーおよびアドレスを作成します。

    public class Address {
          
          
        private String province;
        private String city;
        //setter...getter...略
    }
    public class User {
          
          
        private String name;
        private int age;
        //setter...getter...略
    }
    

最終的に作成されたプロジェクト構造は次のとおりです。

ここに画像の説明を挿入

2. パラメータの受け渡し

GET は単一のパラメータを送信します

リクエストとパラメータを送信します。

http://localhost/commonParam?name=itcast

パラメータを受信します。

@Controller
public class UserController {
    
    

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name){
    
    
        System.out.println("普通参数传递 name ==> "+name);
        return "{'module':'commonParam'}";
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

GET は複数のパラメータを送信します

リクエストとパラメータを送信します。

http://localhost/commonParam?name=itcast&age=15

パラメータを受信します。

@Controller
public class UserController {
    
    

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name,int age){
    
    
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':'commonParam'}";
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

GETリクエストの中国語文字化け

渡すパラメータに中国語が含まれている場合、受け取ったパラメータに中国語の文字化けが含まれることがわかります。

リクエストを送信:http://localhost/commonParam?name=张三&age=18

コンソール:

ここに画像の説明を挿入

文字化けの原因は誰にとっても明らかだと思われますが、Tomcat 8.5 以降のバージョンではすでに中国語の文字化け問題に対応していますが、IDEA の Tomcat プラグインは現在 Tomcat7 までしか対応していないため、pom.xml にはGETリクエストの中国語文字化け問題を解決するために修正予定

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port><!--tomcat端口号-->
          <path>/</path> <!--虚拟目录-->
          <uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
        </configuration>
      </plugin>
    </plugins>
  </build>

ここに画像の説明を挿入

POST送信パラメータ

リクエストとパラメータを送信します。

ここに画像の説明を挿入

変更を加えずに GET と一致します。

@Controller
public class UserController {
    
    

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name,int age){
    
    
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':'commonParam'}";
    }
}
POSTリクエストの中国語文字化け

解決策: フィルターを設定する

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    
    protected Class<?>[] getRootConfigClasses() {
    
    
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
    
    
        return new Class[]{
    
    SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }

    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
    
    
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{
    
    filter};
    }
}

CharacterEncodingFilter は spring-web パッケージに含まれているため、使用する前に対応する jar パッケージをインポートする必要があります。
ここに画像の説明を挿入
ここに画像の説明を挿入

3. 5種類のパラメータ受け渡し

これまでは、GET または POST を使用してリクエストとデータを送信できましたが、送信されるデータは比較的単純なデータでした。次に、これに基づいて、より複雑なパラメータ転送について検討します。一般的なパラメータのタイプは次のとおりです。

  • 共通パラメータ
  • POJO タイプのパラメータ
  • ネストされたPOJOタイプのパラメータ
  • 配列型パラメータ
  • コレクション型パラメータ

これらのパラメータを送信する方法とバックグラウンドで受信する方法を 1 つずつ学習していきましょう。

1. 共通パラメータ

  • 通常パラメータ: URL アドレスパラメータの受け渡し、アドレスパラメータ名は仮パラメータ変数名と同じであり、パラメータを受け取るために仮パラメータを定義できます。

ここに画像の説明を挿入

正式な参加者のアドレスパラメータ名が一致しない場合、問題を解決するにはどうすればよいですか?

リクエストとパラメータを送信します。

http://localhost/commonParamDifferentName?name=张三&age=18

バックグラウンド受信パラメータ:

@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(String userName , int age){
    
    
    System.out.println("普通参数传递 userName ==> "+userName);
    System.out.println("普通参数传递 age ==> "+age);
    return "{'module':'common param different name'}";
}

フロントエンドが指定されname、バックグラウンドが受信に使用されるためuserName、2 つの名前が一致せず、データの受信に失敗します。

ここに画像の説明を挿入

解決策: @RequestParam アノテーションを使用する

@RequestMapping("/commonParamDifferentName")
    @ResponseBody
    public String commonParamDifferentName(@RequestPaam("name") String userName , int age){
    
    
        System.out.println("普通参数传递 userName ==> "+userName);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':'common param different name'}";
    }

注: @RequestParam アノテーション フレームワークを作成する場合は、インジェクションを自分で解析する必要がないため、フレームワークの処理パフォーマンスを向上させることができます。

2.POJOデータ型

一般に、単純なデータ型は比較的少ないパラメーターでリクエストを処理しますが、パラメーターが多い場合、バックグラウンドでパラメーターを受け取るときに処理がより複雑になります。現時点では、POJO データ型の使用を検討できます。

  • POJOパラメータ:リクエストパラメータの名前はパラメータオブジェクトのプロパティ名と同じであり、POJO型パラメータを定義することでパラメータを受け取ることができます

このとき、先ほど用意したPOJOクラスを利用する必要があるので、まずUserを見てみましょう。

public class User {
    
    
    private String name;
    private int age;
    //setter...getter...略
}

リクエストとパラメータを送信します。

ここに画像の説明を挿入

バックグラウンド受信パラメータ:

//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    
    
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

知らせ:

  • フロントエンドのGET、POSTでPOJOパラメータを受け取り、リクエストデータを送信する方法は変わりません。
  • リクエスト パラメータ キーの名前は、POJO 内の属性の名前と一致している必要があります。そうでない場合はカプセル化できません。

3. ネストされたPOJO型パラメータ

他の POJO クラスが POJO オブジェクトにネストされている場合、次のようになります。

public class Address {
    
    
    private String province;
    private String city;
    //setter...getter...略
}
public class User {
    
    
    private String name;
    private int age;
    private Address address;
    //setter...getter...略
}
  • ネストされた POJO パラメータ: リクエスト パラメータ名は仮パラメータ オブジェクトの属性名と同じであり、オブジェクトの階層関係に従ってネストされた POJO 属性パラメータを受け取ることができます。

リクエストとパラメータを送信します。

ここに画像の説明を挿入

バックグラウンド受信パラメータ:

//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    
    
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

ここに画像の説明を挿入

知らせ:

リクエスト パラメータ キーの名前は、POJO 内の属性の名前と一致している必要があります。そうでない場合はカプセル化できません。

4. 配列型パラメータ

簡単な例を挙げると、フロントエンドがユーザーの趣味を取得する必要がある場合、多くの場合、複数の趣味がある場合、リクエストデータを送信し、データを受信するにはどうすればよいでしょうか?

  • 配列パラメータ:リクエストパラメータ名は仮パラメータオブジェクトの属性名と同じで、複数のリクエストパラメータが存在しますパラメータを受け取る配列型を定義します

リクエストとパラメータを送信します。

ここに画像の説明を挿入

バックグラウンド受信パラメータ:

  //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
    
    
        System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
        return "{'module':'array param'}";
    }

5. コレクション型パラメータ

配列は複数の値を受け取ることができるので、コレクションでもこの機能を実現できますか?

リクエストとパラメータを送信します。

ここに画像の説明を挿入

バックグラウンド受信パラメータ:

//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(List<String> likes){
    
    
    System.out.println("集合参数传递 likes ==> "+ likes);
    return "{'module':'list param'}";
}

実行するとエラーが報告されます。

ここに画像の説明を挿入

エラーの理由は次のとおりです。 SpringMVC は List を POJO オブジェクトとして扱い、オブジェクトを作成し、フロントエンド データをオブジェクトにカプセル化する準備をしますが、List はオブジェクトを作成できないインターフェイスであるため、エラーが報告されます。

解決策は、@RequestParamアノテーションを使用することです。

//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
    
    
    System.out.println("集合参数传递 likes ==> "+ likes);
    return "{'module':'list param'}";
}
  • コレクションは通常のパラメーターを保存します。リクエスト パラメーター名は仮パラメーター コレクション オブジェクト名と同じで、複数のリクエスト パラメーターがあり、@RequestParam がパラメーターの関係をバインドします。
  • 単純なデータ型の場合は、コレクションよりも配列を使用する方が簡単です。

知識ポイント 1: @RequestParam

名前 @RequestParam
タイプ 仮パラメータのアノテーション
位置 SpringMVCコントローラーメソッドパラメータ定義前
効果 バインディングリクエストパラメータとプロセッサメソッドパラメータの関係
関連パラメータ required: 必須パラメータかどうか
defaultValue: パラメータのデフォルト値

4. JSONデータ送信パラメータ

前に述べたように、より一般的な開発方法は非同期呼び出しです。表と裏は非同期で交換され、送信されるデータはJSONでは、フロントエンドが JSON データを送信した場合、バックエンドはそれをどのように受信すればよいでしょうか?

JSON データ型には、一般的なものが 3 つあります。

  • json プレーン配列 (["value1", "value2", "value3", ...])
  • json オブジェクト ({key1:value1,key2:value2,…})
  • json オブジェクトの配列 ([{key1:value1,…},{key2:value2,…}])

上記のデータの場合、フロントエンドはどのように送信し、バックエンドはどのように受信するのでしょうか?

JSONプレーン配列

ステップ 1: pom.xml に依存関係を追加する

SpringMVC はデフォルトで jackson を使用して json 変換を処理するため、pom.xml に jackson の依存関係を追加する必要があります。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
ステップ 2: PostMan が JSON データを送信する

ここに画像の説明を挿入

ステップ 3: SpringMVC アノテーションのサポートを有効にする

JSONをオブジェクトに変換する機能を含むSpringMVCの設定クラスでSpringMVCのアノテーションサポートを有効にします。

@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
    
    
}
ステップ 4: パラメータの前に @RequestBody を追加する
//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
    
    
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}
ステップ 5: プログラムを起動して実行する

ここに画像の説明を挿入

JSON通常配列のデータを転送しましたが、JSONオブジェクトデータとJSONオブジェクト配列のデータを転送するにはどうすればよいですか?

JSONオブジェクトデータ

リクエストとデータがどのように送信されるか、バックエンド データがどのように受信されるか、ということだけに注意を払う必要があることがわかります。

リクエストとデータの送信:

{
    
    
"name":"热爱编程的小白白",
"age":21
}

ここに画像の説明を挿入

バックエンドはデータを受信します。

@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
    
    
    System.out.println("pojo(json)参数传递 user ==> "+user);
    return "{'module':'pojo for json param'}";
}

プログラムアクセステストを開始する

ここに画像の説明を挿入

例証します:

アドレスが null になる理由は、フロントエンドがバックエンドにデータを渡さないためです。

アドレスにデータも含めたい場合は、フロントエンドによって渡されるデータの内容を変更する必要があります。

{
    
    
	"name":"张三",
	"age":21,
    "address":{
    
    
        "province":"云南",
        "city":"昆明"
    }
}

リクエストを再度送信すると、アドレス内のデータが表示されます。

ここに画像の説明を挿入

JSON オブジェクトの配列

複数の POJO をコレクションに保存するにはどうすればよいですか?

リクエストとデータの送信:

[
    {
    
    "name":"itcast","age":15},
    {
    
    "name":"itheima","age":12}
]

ここに画像の説明を挿入

バックエンドはデータを受信します。

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
    
    
    System.out.println("list pojo(json)参数传递 list ==> "+list);
    return "{'module':'list pojo for json param'}";
}

プログラムアクセステストを開始する

ここに画像の説明を挿入

まとめ

JSON データを受信する SpringMVC の実装手順は次のとおりです。

(1) ジャクソンパッケージをインポートする

(2) PostManを利用してJSONデータを送信する

(3) SpringMVC アノテーションドライバーを有効にし、構成クラスに @EnableWebMvc アノテーションを追加します

(4) Controllerメソッドのパラメータの前に@RequestBodyアノテーションを追加します

知識ポイント 1: @EnableWebMvc

名前 @EnableWebMvc
タイプ 構成クラスのアノテーション
位置 SpringMVC 構成クラス定義の上
効果 SpringMVCの複数の補助機能を有効にする

知識ポイント 2: @RequestBody

名前 @RequestBody
タイプ 仮パラメータのアノテーション
位置 SpringMVCコントローラーメソッドパラメータ定義前
効果 リクエストボディに含まれるデータをリクエストパラメータに渡します。このアノテーションはハンドラメソッドに対して 1 回のみ使用できます。

@RequestBody と @RequestParam の違い

  • 違い

    • @RequestParam は、URL アドレス渡しパラメータ、フォーム渡しパラメータを受け取るために使用されます [application/x-www-form-urlencoded]
    • @RequestBody は json データを受信するために使用されます [application/json]
  • 応用

    • 開発後期では主にjson形式のデータが送信され、@RequestBodyが広く使われます。
    • 非 JSON 形式でデータを送信する場合は、 @RequestParam を使用してリクエスト パラメーターを受け取ります

5. 日付型パラメータの受け渡し

これまで、単純なデータ型、POJO データ型、配列とコレクションのデータ型、および JSON データ型を扱ってきましたが、次に、開発においてより一般的なデータ型を扱う必要があります。日期类型

日付形式には次のような N 個を超える入力方法があるため、日付型は特別です。

  • 2088-08-18
  • 2088/08/18
  • 2088/08/18

非常に多くの日付形式について、SpringMVC はそれらをどのように受信すればよいでしょうか。また、日付型データを適切に処理できるでしょうか?

ステップ 1: 日付データを受信するメソッドを作成する

UserController クラスにメソッドを追加し、パラメータを日付型に設定します。

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date)
    System.out.println("参数传递 date ==> "+date);
    return "{'module':'data param'}";
}

ステップ 2: Tomcat サーバーを起動する

コンソールでエラーが発生していないか確認し、エラーがある場合はエラーを解決してください。

ステップ 3: PostMan を使用してリクエストを送信する

PostMan を使用して GET リクエストを送信し、日付パラメータを設定します

http://localhost/dataParam?date=2088/08/08

ここに画像の説明を挿入

ステップ 4: コンソールを表示する

ここに画像の説明を挿入

印刷することで、SpringMVC が日付データ型を受け取り、コンソールに出力できることがわかりました。

この時、dateパラメータの形式を別のものに変更してもSpringMVCは扱えるのだろうか?

ステップ 5: 日付形式を変更する

プログラムの実行結果をよりよく確認するために、メソッドに日付パラメータを追加します。

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,Date date1)
    System.out.println("参数传递 date ==> "+date);
    return "{'module':'data param'}";
}

PostMan を使用してリクエストを送信し、2 つの異なる日付形式を伝えます。

http://localhost/dataParam?date=2088/08/08&date1=2088-08-08

ここに画像の説明を挿入

リクエストとデータを送信すると、ページでは 400 が報告され、コンソールではエラーが報告されます。

解決済み [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: タイプ「java.lang.String」の値を必要なタイプ「java.util.Date」に変換できませんでした。ネストされた例外は org.springframework.core.convert です。変換失敗例外: 値 '2088-08-08' の型 [java.lang.String] から型 [java.util.Date] への変換に失敗しました。ネストされた例外は java.lang.IllegalArgumentException です]

エラーメッセージからもわかるように、2088-08-08日付型への変換に失敗したことがエラーの原因であり、SpringMVCでデフォルトでサポートされている文字列から日付までの形式が でありyyyy/MM/dd、現在渡しているものはそうではないためです。 SpringMVC はデフォルトのフォーマットに準拠しているため、フォーマット変換が行われないため、エラーが報告されます。

解決策も比較的単純で、以下を使用する必要があります。@DateTimeFormat

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
                        @DateTimeFormat(pattern="yyyy-MM-dd") Date date1)
    System.out.println("参数传递 date ==> "+date);
	System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
    return "{'module':'data param'}";
}

サーバーを再起動し、リクエストテストを再送信すると、SpringMVC は日付を正しく変換できます。

ここに画像の説明を挿入

ステップ 6: 日付表示時間

次に、日付と時刻を送信して、SpringMVC がそれをどのように処理するかを確認してみましょう。

まず UserController クラスを変更し、3 番目のパラメータを追加します。

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
                        @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
                        @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2)
    System.out.println("参数传递 date ==> "+date);
	System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
	System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
    return "{'module':'data param'}";
}

PostMan を使用してリクエストを送信し、2 つの異なる日付形式を伝えます。

http://localhost/dataParam?date=2088/08/08&date1=2088-08-08&date2=2088/08/08 8:08:08

ここに画像の説明を挿入

サーバーを再起動し、リクエストテストを再送信すると、SpringMVC は日付と時刻のデータを変換できます

ここに画像の説明を挿入

知識ポイント 1: @DateTimeFormat

名前 @DateTimeFormat
タイプ 仮パラメータのアノテーション
位置 SpringMVCコントローラーメソッドの仮パラメータの前
効果 日付と時刻のデータ形式を設定する
関連する属性 pattern: 日付と時刻の形式文字列を指定します。

内部実現原理

内部原理を説明する前に、次の質問について考える必要があります。

  • フロントエンドは文字列を渡し、バックエンドは日付を使用して文字列を受け取ります。
  • フロントエンドは JSON データを渡し、バックエンドはオブジェクトを使用して受信します。
  • フロントエンドは文字列を渡し、バックエンドは整数を使用して受信します。
  • バックグラウンドで必要なデータ型が多数あります
  • データ転送プロセスにはさまざまな種類の変換があります

Q: この型変換は誰が行うのでしょうか?

答え: Spring MVC

Q: SpringMVC は型変換をどのように実装しますか?

回答: SpringMVC は、多くの型変換インターフェイスと実装クラスを提供します。

フレームワークには、次のような型変換インターフェイスがいくつかあります。

  • (1) コンバータインターフェース
/**
*	S: the source type
*	T: the target type
*/
public interface Converter<S, T> {
    
    
    @Nullable
    //该方法就是将从页面上接收的数据(S)转换成我们想要的数据类型(T)返回
    T convert(S source);
}

注: Converter が属するパッケージはorg.springframework.core.convert.converter

Converterインターフェースの実装クラス

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-J6FMrBvz-1682171003114)(assets/1630496385398.png)]

このフレームワークは、Converter インターフェイスに対応する多くの実装クラスを提供します。これらは、次のような異なるデータ型間の変換を実現するために使用されます。

リクエストパラメータの年齢データ(文字列→整数)

日付形式変換(文字列→日付)

  • (2) HttpMessageConverterインターフェース

このインターフェースはオブジェクトとJSON間の変換作業を実装するためのものです

注: SpringMVC の設定クラスは @EnableWebMvc を標準設定として使用します。省略しないでください。

6. 対応

SpringMVCはリクエストとデータを受け取った後、何らかの処理を行うが、もちろんこの処理をServiceに転送し、Service層がDao層を呼び出して完了することもできるが、いずれの場合も処理後は結果を通知する必要があるユーザーに。

例: ユーザー ID に基づいてユーザー情報をクエリする、ユーザー リストをクエリする、新しいユーザーを追加するなど。

応答については、主に次の 2 つの部分で構成されます。

  • 応答ページ
  • 応答データ
    • テキストデータ
    • jsonデータ

現在は非同期呼び出しが主流であるため、JSON データを返す方法に注意を払う必要があり、それ以外については知っていれば十分です。

1. 環境の準備

  • Web Maven プロジェクトを作成する

  • pom.xml は Spring 依存関係を追加します

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.itheima</groupId>
      <artifactId>springmvc_05_response</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.0</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
              <port>80</port>
              <path>/</path>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
    
  • 対応する構成クラスを作成する

    public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          
          
        protected Class<?>[] getRootConfigClasses() {
          
          
            return new Class[0];
        }
    
        protected Class<?>[] getServletConfigClasses() {
          
          
            return new Class[]{
          
          SpringMvcConfig.class};
        }
    
        protected String[] getServletMappings() {
          
          
            return new String[]{
          
          "/"};
        }
    
        //乱码处理
        @Override
        protected Filter[] getServletFilters() {
          
          
            CharacterEncodingFilter filter = new CharacterEncodingFilter();
            filter.setEncoding("UTF-8");
            return new Filter[]{
          
          filter};
        }
    }
    
    @Configuration
    @ComponentScan("com.itheima.controller")
    //开启json数据类型自动转换
    @EnableWebMvc
    public class SpringMvcConfig {
          
          
    }
    
    
    
  • モデルクラスUserを書く

    public class User {
          
          
        private String name;
        private int age;
        //getter...setter...toString省略
    }
    
  • webapp の下に page.jsp を作成します

    <html>
    <body>
    <h2>Hello Spring MVC!</h2>
    </body>
    </html>
    
  • ユーザーコントローラーの書き込み

    @Controller
    public class UserController {
          
          
    
        
    }
    

最終的に作成されたプロジェクト構造は次のとおりです。

ここに画像の説明を挿入

2. 応答ページ [理解する]

ステップ 1: 裏ページを設定する
@Controller
public class UserController {
    
    
    
    @RequestMapping("/toJumpPage")
    //注意
    //1.此处不能添加@ResponseBody,如果加了该注入,会直接将page.jsp当字符串返回前端
    //2.方法需要返回String
    public String toJumpPage(){
    
    
        System.out.println("跳转页面");
        return "page.jsp";
    }
    
}
ステップ 2: プログラムのテストを開始する

これにはページ ジャンプが含まれるため、テストに PostMan を使用するのは適切ではありません。ブラウザを直接開き、次のように入力します。

http://localhost/toJumpPage

ここに画像の説明を挿入

3. テキストデータを返す[理解する]

ステップ 1: 返信テキストの内容を設定する
@Controller
public class UserController {
    
    
    
   	@RequestMapping("/toText")
	//注意此处该注解就不能省略,如果省略了,会把response text当前页面名称去查找,如果没有回报404错误
    @ResponseBody
    public String toText(){
    
    
        System.out.println("返回纯文本数据");
        return "response text";
    }
    
}
ステップ 2: プログラムのテストを開始する

ここではページジャンプはありません。現在送信しているのは GET リクエストであるため、ブラウザまたは PostMan を使用してテストし、アドレスを入力してアクセスできますhttp://localhost/toText

ここに画像の説明を挿入

4. レスポンスのJSONデータ

応答POJOオブジェクト
@Controller
public class UserController {
    
    
    
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
    
    
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("itcast");
        user.setAge(15);
        return user;
    }
    
}

戻り値はエンティティ クラス オブジェクトです。対応するオブジェクトの json データを返すには、戻り値をエンティティ クラスの型に設定します。==@ResponseBody に依存する必要があります。注意事項と@EnableWebMvc==注釈

サーバーを再起動してアクセスしますhttp://localhost/toJsonPOJO

ここに画像の説明を挿入

応答POJOコレクションオブジェクト
@Controller
public class UserController {
    
    
    
    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
    
    
          System.out.println("返回json集合数据");
        User user1 = new User();
        user1.setName("热爱编程的小白白");
        user1.setAge(21);

        User user2 = new User();
        user2.setName("张三");
        user2.setAge(21);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);

        return userList;
    }
    
}

サーバーを再起動してアクセスしますhttp://localhost/toJsonList

ここに画像の説明を挿入

知識ポイント 1: @ResponseBody

名前 @ResponseBody
タイプ メソッド\クラスのアノテーション
位置 SpringMVC コントローラー メソッド定義の上およびコントロール クラス上
効果 現在のコントローラーの戻り値をレスポンスボディとして
クラスに記述します このクラスのすべてのメソッドがこのアノテーション関数を持ちます
関連する属性 pattern: 日付と時刻の形式文字列を指定します。

例証します:

  • このアノテーションはクラスまたはメソッドに記述できます。
  • クラスに書かれているということは、クラス下のすべてのメソッドに @ReponseBody 関数があることを意味します
  • メソッドに @ReponseBody アノテーションが付けられている場合
    • メソッドの戻り値は文字列で、テキスト コンテンツとしてフロント エンドに直接応答されます。
    • メソッドの戻り値はオブジェクトであり、オブジェクトはフロントエンドへの JSON 応答に変換されます。

ここでも型変換が使用されており、Converter インターフェイスの実装クラスを通じて内部で完了するため、Converter は上記の関数に加えて次の機能も実装できます。

  • オブジェクトから Json データへ (POJO -> json)
  • コレクションからJsonデータへ (コレクション -> json)

出典: Dark Horse Programmer SSM フレームワーク チュートリアル

おすすめ

転載: blog.csdn.net/Javascript_tsj/article/details/130312536