<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring MVC的基本使用1

      1、Spring MVC的基本介紹

      spring mvc 是基于 spring 的一個框架,實際上就是 spring 的一個模塊,是專門用來做 web 開發的。spring mvc 的底層實際上還是 servlet ,只是在 servlet 的基礎上面加入了一些功能,讓 web 開發更加方便,可以理解為是 servlet 的升級。

      Spring MVC 框架是圍繞一個 DispatcherServlet(中央調度器) 來設計的,這個Servlet會把請求分發給各個處理器,由各個處理器來處理請求(處理器就是應用中注解了 @Controller 和 @RequestMapping 的類和方法)。DispatcherServlet其實就是個Servlet(它繼承自HttpServlet基類),DispatcherServlet 也被稱之為前端控制器。

      DispatcherServlet處理請求的工作流如下:

       

      2、SpringMVC的基本使用

      2.1、springmvc的使用

      先在 idea 中通過 maven 創建一個 web 項目,創建完成后我們可以手動添加 src/main/java 和 src/main/resource 目錄:

      然后引入依賴,依賴配置文件 pom.xml 類似下面:

      <?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>org.example</groupId>
        <artifactId>maven_ee_test01</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
      
        <dependencies>
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
          </dependency>
          <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.5.RELEASE</version>
          </dependency>
        </dependencies>
      </project>

       

      在 maven 的 web 項目的 web.xml 配置文件中配置中央調度器。默認生成的 web.xml 配置文件跟下面不太一樣,可以直接照著下面進行修改:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
      
        <!-- SpringMVC的前端控制器 -->
        <servlet>
          <servlet-name>springmvcTest</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      
      
          <!-- 可以自定義springmvc讀取的配置文件的位置 -->
      <!--    <init-param>-->
      <!--      <param-name>contextConfigLocation</param-name>-->
      <!--      <param-value>/WEB-INF/xxx.xml</param-value>  &lt;!&ndash;指定配置文件的位置&ndash;&gt;-->
      <!--    </init-param>-->
      
      
          <!-- 指定該servlet對象在tomcat啟動時即創建。
               load-on-startup:指定tomcat啟動后創建對象的順序,tomcat會根據各個servlet的該屬性值按照順序來創建各個servlet對象。它的值是大于等于0的整數,值越小創建時間越早。-->
          <load-on-startup>1</load-on-startup>
        </servlet>
      
        <servlet-mapping>
          <servlet-name>springmvcTest</servlet-name>
      
          <!-- 使用框架時,url-pattern一般來說有兩種寫法:
                  1)使用自定義擴展名:*.do、*.action、*.mvc等等,如<url-pattern>*.do</url-pattern>
                  2)直接使用斜桿:<url-pattern>/</url-pattern>,表示攔截所有請求
          -->
          <url-pattern>*.do</url-pattern>
        </servlet-mapping>
      </web-app>

      DispatcherServlet 實際上就是個 servlet(它繼承自HttpServlet基類),在被創建時,會執行該 servlet 的 init() 方法。在 DispatcherServlet 的初始化過程中,該框架會嘗試拿到項目中的 WebContent/WEB-INF 目錄文件下的名為 [servlet-name]-servlet.xml 的配置文件,并創建其中所定義的bean。(比如是上面的配置,則該配置文件將會是 webcontent/WEB-INF/springmvcTest-servlet.xml,springmvc 會從該配置文件中加載應用程序上下文)。當然,我們也可以通過 init-param 標簽自定義配置文件的位置及名稱,不使用默認的。

      然后我們需要在 webcontent(webapp)/WEB-INF 目錄下創建一個 spring 配置文件,并在該文件中開啟組件掃描。比如下面的 springmvcTest-servlet.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
      
          <!--開啟組件掃描。base-package寫包名,若要掃描多個包,可以用逗號隔開,或者直接寫多個包共用的上級目錄-->
          <context:component-scan base-package="controllerPackage"></context:component-scan>
      </beans>

      (中央調度器  DispatcherServlet 負責創建 springmvc 容器 對象,讀取 spring 的 xml 配置文件,創建文件中的 Controller 對象。并且負責接收用戶的請求,分派給各個 Controller 對象。)

       

      然后需要創建控制器,通過控制器來處理請求。比如下面我們創建了一個控制器類,通過注解 @RequestMapping 來將URL映射到處理方法中,即 /test.do 請求將會由 doTest() 方法來處理:

      package controllerPackage;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.servlet.ModelAndView;
      
      @Controller
      public class ControllerTest01 {
          /**
           *創建方法來處理請求,在springmvc中是通過方法來處理請求的。方法是自定義的,有多種返回值,多種參數
           * @RequestMapping:請求映射,作用是把請求地址和方法綁定在一起。屬性的value可以是一個string,也可以是一個數組,不同方法間的值不能重復。
           * @RequestMapping 可以放在方法上,也可以直接放在類上
           */
          @RequestMapping(value = "/test.do")
          public ModelAndView doTest() {
              //Spring MVC 通過 ModelAndView 對象把模型和視圖結合在一起
              ModelAndView modelView = new ModelAndView();
      
              //添加數據,框架最后會把數據放到request的作用域當中,類似于 request.setAttribute()
              modelView.addObject("name","張三");
              modelView.addObject("age","22");
      
              //指定視圖,指定視圖的完整路徑??蚣軙σ晥D執行forward操作,類似于request.getRequestDispatcher("/show.jsp").forward();
              modelView.setViewName("/show.jsp");
              return modelView;
          }
      }

       在項目 src/main/webapp 目錄下創建 show.jsp,用來接收上面處理 /test.do 過后添加的數據:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
          <h1>這里是show.jsp頁面</h1>
      
          <h2>hello:${name} ---- ${age}</h2>
      
      </body>
      </html>

       

      然后我們就可以通過訪問 test.do 來進行測試了。啟動 tomcat,添加項目,訪問 test.do 請求。比如項目名為 springmvcProject,則訪問路徑為:http://localhost:8080/springmvcProject/test.do。最后可以看到結果如下:

       

      2.2、配置視圖解析器(統一指定視圖的前綴和后綴)

      上面的示例,我們把 show.jsp 建在了 webapp 目錄下,這樣的話用戶可以直接通過訪問 jsp 頁面的路徑來訪問頁面,而不是通過接口 .do 的形式來訪問,而不通過接口就無法拿到數據,可能會出現下面這種情況:

      如果我們不希望用戶可以直接訪問到 jsp 頁面,我們可以把頁面文件建在 WEB-INF 目錄下,這樣用戶就無法通過輸入頁面路徑來直接訪問頁面,因為 WEB-INF 下的資源是無法通過瀏覽器直接訪問的。比如:

      這樣我們指定視圖就可以寫成:

      modelView.setViewName("/WEB-INF/view/show.jsp");

       

      在指定視圖的時候,有可能有大量的重復路徑,例如:

      mv.setViewName("/WEB-INF/view/show1.jsp");
      mv.setViewName("/WEB-INF/view/show2.jsp");
      mv.setViewName("/WEB-INF/view/show3.jsp");

      我們可以在 spring 的配置文件中配置視圖解析器,可以指定視圖的前綴(路徑)和后綴(擴展名),讓框架來找到對應的視圖文件。例如,修改 springmvcTest-servlet.xml 文件:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
      
          <!--開啟組件掃描。base-package寫包名,若要掃描多個包,可以用逗號隔開,或者直接寫多個包共用的上級目錄-->
          <context:component-scan base-package="controllerPackage"></context:component-scan>
      
          <!-- springmvc框架中的視圖解析器-->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <!-- 前綴:視圖文件的路徑-->
              <property name="prefix" value="/WEB-INF/view/"/>
              <!-- 后綴:視圖文件的擴展名-->
              <property name="suffix" value=".jsp"/>
          </bean>
      </beans>

      在配置了視圖解析器后就可以直接用邏輯名稱(文件名)來指定視圖,框架會使用 “視圖解析器前綴+邏輯名稱+視圖解析器后綴” 來組成完整的路徑。

      示例:

      mv.setViewName("show1");   //相當于 mv.setViewName("/WEB-INF/view/show1.jsp");
      mv.setViewName("show2");
      mv.setViewName("show3");

       

      2.3、解決訪問靜態資源報404的問題

      中央調度器的 url-pattern 可以使用自定義擴展名,如:*.do、*.action、*.mvc等等,如<url-pattern>*.do</url-pattern>;也可以直接使用斜桿:<url-pattern>/</url-pattern>,表示攔截所有請求。當我們直接使用斜桿來攔截所有請求時,你會發現,在使用瀏覽器訪問靜態資源(比如html、css、img等)時會報 404。(在某些時候如果我們不希望通過 .do 來訪問后端接口,此時可以將 url-pattern 配置成 /,這樣就不需要給接口名后面添加 .do 后綴,直接寫即可,比如 @RequestMapping(value = "/test01"))

      默認情況下,tomcat 會有一個 default 的 servlet(該 servlet 可以在 tomcat 安裝目錄下的 conf/web.xml 文件中找到),該 servlet 的 url-pattern 是 /,即攔截所有請求。當我們將中央調度器的 url-pattern 設置為 / 時,該中央調度器會替代 tomcat 的默認的 servlet,而因為中央調度器默認沒有處理靜態資源的能力,所以訪問靜態資源會報 404,但是訪問動態資源比如 xxx.do 能正常訪問。

       

      所以當我們將中央調度器的 url-pattern 配置成 / 時,需要解決靜態資源訪問不到的問題。解決方法有以下兩種:

      1)使用<mvc:default-servlet-handler />

      在 spring 的配置文件(比如springmvcTest-servlet.xml)中配置<mvc:default-servlet-handler />,如下:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!--開啟組件掃描。base-package寫包名,若要掃描多個包,可以用逗號隔開,或者直接寫多個包共用的上級目錄-->
          <context:component-scan base-package="controllerPackage"></context:component-scan>
      
          <!--注解驅動-->
          <mvc:annotation-driven/>
      
          <mvc:default-servlet-handler />
      </beans>

      配置<mvc:default-servlet-handler />后,Spring MVC上下文中會定義一個org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它會像一個檢查員,對進入DispatcherServlet的URL進行篩查,如果發現是靜態資源的請求,就將該請求轉由Web應用服務器默認的 Servlet 處理,如果不是靜態資源的請求,才由DispatcherServlet繼續處理。

      在配置了 <mvc:default-servlet-handler /> 后,訪問 @RequestMapping 注解的方法可能報 404,這是因為 <mvc:default-servlet-handler /> 和 @RequestMapping 注解有沖突,此時我們在 spring  的配置文件上添加注解驅動即可。

       

      2)使用<mvc:resources />

      第一種方法即 <mvc:default-servlet-handler /> 是將靜態資源的處理 由Spring MVC 框架交回給了 tomcat 處理。而使用 <mvc:resources /> 則是由Spring MVC框架自己處理靜態資源,并可以添加一些有用的附加值功能。

      在 spring 的配置文件下添加 <mvc:resources /> 標簽,示例:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!--開啟組件掃描。base-package寫包名,若要掃描多個包,可以用逗號隔開,或者直接寫多個包共用的上級目錄-->
          <context:component-scan base-package="controllerPackage"></context:component-scan>
      
      
          <!--<mvc:resources /> 標簽 和 @RequestMapping 注解有沖突,所以需要添加注解驅動-->
          <mvc:annotation-driven/>
      
          <!--
              mapping指的是瀏覽器訪問資源的路徑,比如http:localhost:8080/應用名/static/home.html
              locatioon指的是在服務器內,靜態資源存放的位置,比如下面的即表示靜態資源是在 webapp/static 目錄下
          -->
          <mvc:resources mapping="/static/**" location="/static/" />
      
          <!-- 可以定義多個mvc:resource標簽,為不同目錄下的靜態資源定義不同的mapping和location,但是建議將靜態資源都放在同一個文件夾下,比如 webapp/static 下,這樣就可以只保留上面一個標簽-->
          <mvc:resources mapping="/css/**" location="/css/" />
      
      </beans>

      使用 <mvc:resources /> 允許靜態資源放在任何地方,如 WEB-INF目錄下、類路徑下等。通過 location屬性指定靜態資源的位置,由于location屬性是Resources類型,因此可以使用諸如"classpath:"等的資源前綴指定資源位置。傳統Web容器的靜態資源只能放在Web容器的根路徑下,<mvc:resources />完全打破了這個限制。

      其次,<mvc:resources />依據當前著名的Page Speed、YSlow等瀏覽器優化原則對靜態資源提供優化。你可以通過cacheSeconds屬性指定靜態資源在瀏覽器端的緩存時間,一般可將該時間設置為一年,以充分利用瀏覽器端的緩存。在輸出靜態資源時,會根據配置設置好響應報文頭的Expires 和 Cache-Control值。在接收到靜態資源的獲取請求時,會檢查請求頭的Last-Modified值,如果靜態資源沒有發生變化,則直接返回303相應狀態碼,提示客戶端使用瀏覽器緩存的數據,而非將靜態資源的內容輸出到客戶端,以充分節省帶寬,提高程序性能。

       

      3、@RequestMapping注解

      @RequestMapping 將請求地址和方法綁定在一起。屬性的value可以是一個string,也可以是一個數組,不同方法間的值不能重復。

       

      3.1、@RequestMapping作用在類上

      @RequestMapping 既可以作用在方法上,也可以作用在類上。當@RequestMapping 標記在Controller 類上的時候,類里面使用@RequestMapping 標記的方法的請求地址都是相對于類上的@RequestMapping 而言的。簡單來說,就是給類上的方法統一加了一個前綴。

      示例:

      package controllerPackage;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.servlet.ModelAndView;
      
      @Controller
      @RequestMapping("/user")
      public class ControllerTest02 {
          @RequestMapping(value = "/test1.do")
          public ModelAndView doTest() {
              ...
          }
      
          @RequestMapping(value = "/test2.do")
          public ModelAndView doTest2() {
              ...
          }
      }

      此時訪問 test1.do 或者 test2.do 實際上應該訪問的路徑為:localhost:8080/項目名/user/test1.do。注意,需要在前面加上 /user。

       

      3.2、method 屬性

      @RequestMapping 的 method 屬性可以指定方法只能被指定的請求方式訪問,如果不指定請求方式時,則表示不限制請求方式,即任何方式都行。該屬性的值是 RequestMethod 類枚舉值,比如:RequestMethod.GET、RequestMethod.POST 等等。

      示例:

      package controllerPackage;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.servlet.ModelAndView;
      
      @Controller
      @RequestMapping("/user")
      public class ControllerTest02 {
          @RequestMapping(value = "/test1.do", method = RequestMethod.GET)
          public ModelAndView doTest() {
              ...
          }
      
          @RequestMapping(value = "/test2.do", method = {RequestMethod.GET, RequestMethod.DELETE})
          public ModelAndView doTest2() {
               ...
          }
      }

      指定了請求方式后,如果使用非指定的請求方式來訪問接口的話,瀏覽器會報 405,提示該請求方式不被支持。

       

      4、處理器方法接收前端請求的參數

      4.1、通過HttpServletRequest對象獲取參數

      可以給 @RequestMapping 注解的方法添加 HttpServletRequest 對象的屬性,通過該對象可以獲取到前端請求的參數:

      @Controller
      public class ControllerTest03 {
          @RequestMapping(value = "/test01.do")
          public ModelAndView doTest(HttpServletRequest request, HttpServletResponse response, HttpSession httpSessiont) {
              System.out.println(request.getParameter("name"));  // 獲取到前端發送的name屬性值
              
              //...
          }
      }

      我們可以通過訪問類似 http://localhost:8080/springmvcProject/test01.do?name=zhangsan 的地址給后臺接口發送數據,后臺接口即可接收到 name 屬性的值。

       

      4.2、通過同名形參直接獲取參數

      可以給 @RequestMapping 注解的方法添加跟前端發送的參數同名的形參,即可通過形參來直接獲取前端發送的同名參數:

      @Controller
      public class ControllerTest03 {
          @RequestMapping(value = "/test01.do")
          public ModelAndView doTest(String name, int age) {
              System.out.println(name + "----" + age);  //直接獲取到前端發送的name和age參數值
      
              //...
          }
      }

      我們可以通過訪問類似 http://localhost:8080/springmvcProject/test01.do?name=zhangsan&age=22 的地址給后臺接口發送數據,后臺接口即可接收到對應的參數值。

      這種通過同名形參直接獲取前端同名參數的方法,實際上是 springmvc 框架通過 HttpServletRequest 對象的 getParameter() 方法來將前端參數賦值給對應的形參的。并且框架同時還提供類型轉換的功能,例如上面,會先將 age 的值轉換為 int 類型,然后再賦值給形參 age。

       

      4.3、形參和實參不同名(@RequestParam())

      通過與參數同名的形參能夠直接獲取前端參數,但如果不同名,我們也可以通過 @RequestParam() 注解來指定參數的別名來獲取參數。

      @Controller
      public class ControllerTest02 {
          @RequestMapping(value = "/test3.do")
          public ModelAndView doTest2(@RequestParam(name = "othername") String name) {
              System.out.println(name);
      
              //...
          }
      }

      如上,前端請求的參數可以是 othername。通過 @RequestParam(name = "othername") 和 @RequestParam(value = "othername")  或者不加屬性值即 @RequestParam("othername") 設置都一樣。

      @RequestParam() 還可以設置屬性值 required 為 false,即 @RequestParam(required = false),此時前端可以不用傳該參數 java 程序也不會報錯。

       

      4.4、通過對象來獲取參數

      如果參數過多,一個個寫參數可能比較麻煩,此時我們可以定義一個 Java 實體類,該類的屬性名跟前端參數名對應,通過類的對象作為形參來獲取參數。

      示例:

      定義一個實體類:

      public class Person {
          String name;
          int age;
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      }

      將該類的對象作為形參,springmvc 框架會自動創建形參中類的對象,并且調用該對象的 setter 方法給屬性賦值:

      @Controller
      public class ControllerTest02 {
          @RequestMapping(value = "/test4.do")
          public ModelAndView doTest4(Person person) {
              System.out.println(person.getName());
      
              //...
          }
      }

       

      4.5、配置字符編碼過濾器(解決中文亂碼問題)

      在獲取前端中文參數時,可能會出現亂碼問題。如果使用 HttpServletResponse 對象來返回數據,可以使用 resp.setContentType("text/html;charset=utf-8"); 來解決中文亂碼問題,但需要在每個請求里都設置,比較麻煩。

      我們可以在 WEB-INF/web.xml 的配置文件里設置字符編碼過濾器來統一解決編碼問題。

      示例:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
      
        ...
      
        <!-- characterEncodingFilter字符編碼過濾器 -->
        <filter>
          <filter-name>characterEncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param> <!--要使用的字符集,一般使用UTF-8--> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param>
      <init-param> <!--是否強制設置request的編碼為encoding,默認為false--> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param>
      <init-param> <!--是否強制設置response的編碼為encoding--> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter>
      <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <!--這里不能留空或者直接寫'/',否則不起作用--> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>

      上面設置編碼過后,返回給前端的數據編碼將會是 utf-8,解決中文亂碼問題。

      但是設置了上面字符編碼過濾器后,如果直接訪問服務器中的 html 頁面,你會發現 html 頁面里的中文變亂碼了。此時將 forceRequestEncoding 和 forceResponseEncoding 去掉即可。

       

      5、響應請求返回數據

      5.1、返回ModelAndView類型(響應一個jsp頁面)

      若處理器方法處理完,需要跳轉其它 jsp 資源,并且需要傳遞數據,則可以返回 ModelAndView 。此時JSP頁面可以使用 JSTL 標簽來匹配解析后端返回的數據。

      示例:

      package controllerPackage;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.servlet.ModelAndView;
      @Controller
      public class ControllerTest01 {
          @RequestMapping(value = "/test.do")
          public ModelAndView doTest() {
              ModelAndView modelView = new ModelAndView();
              modelView.addObject("name","張三");
              modelView.addObject("age","22");
              modelView.setViewName("/show.jsp");
              return modelView;
          }
      }

       

      5.2、返回String(響應一個jsp頁面)

      處理器方法可以返回字符串,該字符串可以是邏輯名稱(文件名稱),也可以是完整的視圖路徑。最終該處理方法會跳轉到該字符串所指定的資源。

      示例:

      package controllerPackage;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.servlet.ModelAndView;
      
      @Controller
      public class ControllerTest02 {
      
          @RequestMapping(value = "/returnStringTest.do")
          public String doTest() {
              //框架實際上是對視圖執行forward操作
              return "/WEB-INF/view/show1.jsp";   //或者如果我們配置了視圖解析器,則應該直接寫邏輯名稱,比如:show1
          }
      }

       

      5.3、返回值為void(響應ajax請求)

      在返回值為 void 時,我們可以用來響應 ajax 請求。

      package controllerPackage;
      
      import com.alibaba.fastjson.JSON;
      ...
      
      @Controller
      public class ControllerTest02 {
      
          //直接給 ajax 請求返回字符串
          @RequestMapping("/ajaxResponse.do")
          public void ajaxResponse(HttpServletRequest request, HttpServletResponse response) throws Exception{
              PrintWriter out = response.getWriter();
              out.write("hello");
          }
      
          //給 ajax 請求返回一個json格式字符串
          @RequestMapping("/ajaxJson.do")
          public void ajaxJson(HttpServletRequest request, HttpServletResponse response) throws Exception{
              PrintWriter out = response.getWriter();
      
              //通過 com.alibaba.fastjson.JSON 包來將對象轉換成json格式字符串
              Student student = new Student(1, "wen");
              String stuStr = JSON.toJSONString(student);
      
              out.write(stuStr);
          }
      }

       

      5.4、返回Object類型(包括Integer、String、Map、List、自定義對象等等,響應ajax請求)

      處理器也可以返回 Object 對象,這個對象可以是 Integer、String、Map、List、自定義對象等等。但返回的對象不是作為邏輯視圖出現的,而是直接給前端請求返回數據的。

      首先需要先引入處理 json 的工具庫,springmvc 中默認使用的是 jackson:

      <?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>org.example</groupId>
        <artifactId>springmvc_maven_test01</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.5.RELEASE</version>
          </dependency>
      
          <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.4</version>
          </dependency>
          <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
          </dependency>
          <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.4</version>
          </dependency>
      
        </dependencies>
      
          ...
      </project>

      然后給 spring 的配置文件添加注解驅動。

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!--開啟組件掃描。base-package寫包名,若要掃描多個包,可以用逗號隔開,或者直接寫多個包共用的上級目錄-->
          <context:component-scan base-package="controllerPackage"></context:component-scan>
      
          <!--注解驅動-->
          <mvc:annotation-driven/>
      </beans>

      添加注解驅動時需要注意是添加 mvc 的,不要添加成其他同名的。

       

      注解驅動的作用是將 java 對象轉換為 json、xml、text、二進制等格式數據,框架會自動識別 java 對象能轉換為什么數據格式,然后進行返回。<mvc:annotation-driven/> 在加入到配置文件后,會自動創建 HttpMessageConverter 接口的實現類對象,這個接口的實現類完成了 java 對象到其他數據格式的轉換功能。

       

      在使用時需要在方法前添加 @ResponseBody 注解,springmvc 通過該注解將會把處理器方法已經轉換后生成的數據通過 HttpServletResponse 返回給前端的 ajax 請求。

      代碼示例:

      package controllerPackage;
      import entity.Student;
      ...
      
      @Controller
      public class ControllerTest03 {
      
          @RequestMapping("/objJson.do")
          @ResponseBody   //把處理器方法返回的對象轉換為json后,通過HttpServletResponse返回給前端
          public Student objJson(HttpServletRequest request, HttpServletResponse response){
      
              Student student = new Student(1, "wen");
              return student;
          }
      }

      返回一個類對象,前端接收到的字符串轉換為 json 格式后將會是一個對象 obj。

      如果返回的是一個 Map,則前端接收到的字符串經轉換為 json 后也是一個對象 obj;如果返回的是一個 list,則前端接收到的字符串經轉換為 json 后將會是一個數組,并且順序跟 list 添加元素的順序一致;如果是一個字符串 String,前端接收到的也是字符串。

      代碼示例:

      package controllerPackage;
      
      import entity.Student;
      ...
      
      @Controller
      public class ControllerTest03 {
      
          //返回一個list
          @RequestMapping("/objList.do")
          @ResponseBody   //把處理器方法返回的對象轉換為json后,通過HttpServletResponse返回給前端
          public List<Student> objList(HttpServletRequest request, HttpServletResponse response){
              List<Student> list = new ArrayList<>();
              Student student1 = new Student(1, "wen");
              Student student2 = new Student(2, "wen2");
      
              list.add(student1);
              list.add(student2);
      
              return list;
          }
      
          //返回一個map
          @RequestMapping("/objMap.do")
          @ResponseBody   //把處理器方法返回的對象轉換為json后,通過HttpServletResponse返回給前端
          public Map<String, String> objMap(HttpServletRequest request, HttpServletResponse response){
              Map<String, String> testMap = new HashMap<>();
              testMap.put("hello", "你好");
              testMap.put("world", "世界");
              return testMap;
          }
      
          //直接返回字符串
          @RequestMapping("/objString.do")
          @ResponseBody   //把處理器方法返回的對象轉換為json后,通過HttpServletResponse返回給前端
          public String objString(HttpServletRequest request, HttpServletResponse response){
              return "你好啊hello~";
          }
      
      }

       

      5.4.1、解決返回 String 時中文亂碼問題

      使用上述方法來返回 String 時,如果字符串中有中文,則前端接收到的數據可能會有中文亂碼問題(注意,此時返回字符串是直接返回數據,而不是返回視圖 jsp 資源)。出現中文亂碼問題這是默認返回的響應頭 content-type 中指定的編碼格式是 ISO-8859-1,如下:

       

       解決中文亂碼問題我們可以通過 @RequestMapping 注解的 produces 屬性來指定響應頭的 content-type,如下:

      @Controller
      public class ControllerTest03 {
          @RequestMapping(value = "/objString.do", produces = "text/html;charset=utf-8")  //produces相當于給response指定了Content-Type響應頭
          @ResponseBody
          public String objString(HttpServletRequest request, HttpServletResponse response){
              return "你好啊hello~";
          }
      }

       

      6、Springmvc接收各種參數(字符串、json)

      6.1、接收普通參數

      前端發送請求方法:

      $.ajax({
          url: 'getStr.do',
          type: 'post',  //此時get請求和post請求發送參數的寫法一樣
          data: {
              name: 'wen',
              age: 11
          },
          success: function (data) {
              console.log('后端返回數據', data);  //這里將接收到后端返回的字符串
          }
      })

      springmvc 代碼,請求參數名跟Controller的方法參數一致:

      @Controller
      public class ControllerTest01 {
      
          @RequestMapping(value = "/getStr.do", produces = "text/html;charset=utf-8")
          @ResponseBody
          public String doTest(String name, int age) {
              System.out.println(name + "----" + age);  //直接獲取到前端發送的name和age參數值
      
              return "你好啊hello~";
          }
      
      }

      此時可以看到前端發送的 url、響應頭 content-type、發送頭 content-type 和參數如下:

       

      6.2、將對象作為參數

      當請求參數過多時,后端可以以對象作為參數接收前端發送的數據,而此時前端發送數據跟發送普通參數一樣。

      前端代碼如下,此時發送數據跟發送普通參數一致:

      $.ajax({
          url: 'getObj.do',
          type: 'post',
          data: {
              name: 'wen',
              age: 11
          },
          success: function (data) {
              console.log('后端返回數據', data)
          }
      })

      實體類如下,實體類可以寫構造函數也可以不寫。

      package domain;
      
      public class Student {
          String name;
          int age;
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
      
          public Student(String name, int age) {
              System.out.println(11112222);
              this.name = name;
              this.age = age;
          }
      }

      controller 類:

      @Controller
      public class ControllerTest01 {
      
          @RequestMapping(value = "/getObj.do")  //此時不能寫produces = "text/html;charset=utf-8" 因為此時返回的是對象,默認將是json格式,如果寫成text/html將導致接口有問題
          @ResponseBody
          public Student doTest02(Student student) {
              System.out.println(student.getName() + "----" + student.getAge());
      
              return student;
          }
      }

      此時可以看到前端發送的 url、響應頭 content-type、發送頭 content-type 和參數如下:

       

       

      6.3、接收復雜對象

      如果接收的是復雜對象,比如對象當中還嵌套著對象。此時前端發送請求時需指定 content-type 為 'application/json;charset=utf-8',并且后端需要用 @RequestBody 進行接收。

      前端發送參數格式如下:

      $.ajax({
          url: 'getComplexObj.do',
          contentType: 'application/json;charset=utf-8',
          type: 'post',
          data: JSON.stringify({
              complexName: '復雜對象名',    //這里也可以是一個對象,這樣的話此時后端的實體類中該字段也應該是一個實體類
              student: {
                  name: '學生名',
                  age: 111
              }
          }),
          success: function (data) {
              console.log('后端返回數據', data)
          }
      })

      復雜對象類:

      package domain;
      
      public class ComplexDomain {
          private Student student;  //注意,此時student類中不能有自定義構造函數
          private String complexName;
      
          public Student getStudent() {
              return student;
          }
      
          public void setStudent(Student student) {
              this.student = student;
          }
      
          public String getComplexName() {
              return complexName;
          }
      
          public void setComplexName(String complexName) {
              this.complexName = complexName;
          }
      }

      controller類:

      @Controller
      public class ControllerTest01 {
      
          @RequestMapping(value = "/getComplexObj.do")
          @ResponseBody
          public ComplexDomain doTest03(@RequestBody ComplexDomain complexDomain) {
              System.out.println(complexDomain.getComplexName() + "----" + complexDomain.getStudent().getName() + "----" + complexDomain.getStudent().getAge()); 
      
              return complexDomain;
          }
      
      }

      此時可以看到前端發送的 url、響應頭 content-type、發送頭 content-type 和參數如下:

       

       

       

      posted @ 2021-05-11 18:21  wenxuehai  閱讀(516)  評論(0)    收藏  舉報
      //右下角添加目錄
      主站蜘蛛池模板: 久久久亚洲欧洲日产国码农村| 一区天堂中文最新版在线| 精品一区二区三区国产馆| 人人做人人澡人人人爽| 亚洲an日韩专区在线| 久久国产自偷自偷免费一区| 中文字幕有码在线第十页| 亚洲综合一区二区三区| 国产成人综合亚洲欧美日韩| 人妻激情文学| 亚洲av成人免费在线| 国产精品国产精品一区精品| 五月婷婷中文字幕| 国产精品日本一区二区不卡视频| 久视频久免费视频久免费| 国产精品乱码久久久久久小说| 久章草在线毛片视频播放| 高安市| 国产日韩精品视频无码| 国产高清一区二区不卡| 精品人妻码一区二区三区| 樱花草视频www日本韩国| 中文www天堂| 色偷偷亚洲女人天堂观看| 陈巴尔虎旗| 成人免费在线播放av| 日韩精品视频一二三四区| 久久精品夜色噜噜亚洲av| 久久综合五月丁香六月丁香| 九九热视频精品在线播放| 女同久久一区二区三区| 韩国午夜理伦三级| 丁香婷婷综合激情五月色| 欧洲亚洲国内老熟女超碰| 日本久久99成人网站| 国产成人精品中文字幕| 久久久无码精品国产一区| 在线无码免费看黄网站| 亚洲精品国偷拍自产在线观看蜜臀| 亚洲精品日韩在线观看| 久久亚洲国产精品久久|