天天看點

SpringMVC工程基礎入門實踐

【1】注冊SpringMVC的前端控制器DispatcherServlet

① 預設配置方式

此配置作用下,SpringMVC的配置檔案預設位于​

​WEB-INF​

​​下,預設名稱為​

​<servlet-name>-servlet.xml​

​​,例如,以下配置所對應​

​SpringMVC​

​​的配置檔案位于​

​WEB-INF​

​​下,檔案名為​

​springMVCservlet.xml​

<!-- 配置SpringMVC的前端控制器,對浏覽器發送的請求統一進行處理 -->
<servlet>
  <servlet-name>springMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servletclass>
</servlet>
<servlet-mapping>
  <servlet-name>springMVC</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>      

設定​

​springMVC​

​​的核心控制器所能處理的請求的請求路徑。​

​/​

​​所比對的請求可以是​

​/login​

​​或​

​.html​

​​或​

​.js​

​​或​

​.css​

​​方式的請求路徑,但是​

​/​

​​不能比對​

​.jsp​

​請求路徑的請求。

② 擴充配置方式

可通過​

​init-param​

​​标簽設定SpringMVC配置檔案的位置和名稱,通過​

​load-on-startup​

​​标簽設定

SpringMVC前端控制器DispatcherServlet的初始化時間

<!-- 配置SpringMVC的前端控制器,對浏覽器發送的請求統一進行處理 -->
<servlet>
  <servlet-name>springMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servletclass>
  <!-- 通過初始化參數指定SpringMVC配置檔案的位置和名稱 -->
  <init-param>
  <!-- contextConfigLocation為固定值 -->
  <param-name>contextConfigLocation</param-name>
  <!-- 使用classpath:表示從類路徑查找配置檔案,例如maven工程中的src/main/resources -->
  <param-value>classpath:springMVC.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springMVC</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>      

​<url-pattern>​

​标簽中使用​

​/​

​和​

​/*​

​的差別

​/​

​​所比對的請求可以是​

​/login或.html或.js或.css方式​

​​的請求路徑,但是​

​/​

​​不能比對​

​.jsp​

​​請求路徑的請

求.是以就可以避免在通路jsp頁面時,該請求被DispatcherServlet處理,進而找不到相應的頁面​​

​/*​

​​則能夠比對所有請求。例如在使用過濾器時,若需要對所有請求進行過濾,就需要使用​

​/*​

​的寫法。

【2】與Thymeleaf整合

建立springMVC的配置檔案

<!-- 自動掃描包 -->
<context:component-scan base-package="com.mvc.controller"/>
<!-- 配置Thymeleaf視圖解析器 -->
<bean id="viewResolver"
  class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
  <property name="order" value="1"/>
  <property name="characterEncoding" value="UTF-8"/>
  <property name="templateEngine">
    <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
      <property name="templateResolver">
        <bean
          class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
          <!-- 視圖字首 -->
          <property name="prefix" value="/WEB-INF/templates/"/>
          <!-- 視圖字尾 -->
          <property name="suffix" value=".html"/>
          <property name="templateMode" value="HTML5"/>
          <property name="characterEncoding" value="UTF-8" />
        </bean>
      </property>
    </bean>
  </property>
</bean>

<!--
處理靜态資源,例如html、js、css、jpg若隻設定該标簽,則隻能通路靜态資源,其他請求則無法通路
此時必須設定<mvc:annotation-driven/>解決問題
-->
<mvc:default-servlet-handler/>

<!-- 開啟mvc注解驅動 -->
<mvc:annotation-driven>
  <mvc:message-converters>
    <!-- 處理響應中文内容亂碼 -->
    <bean
      class="org.springframework.http.converter.StringHttpMessageConverter">
      <property name="defaultCharset" value="UTF-8" />
      <property name="supportedMediaTypes">
        <list>
          <value>text/html</value>
          <value>application/json</value>
        </list>
      </property>
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>      

浏覽器發送請求,若請求位址符合前端控制器的​

​url-pattern​

​​,該請求就會被前端控制器​

​DispatcherServlet​

​​處理。前端控制器會讀取SpringMVC的核心配置檔案,通過掃描元件找到控制器,将請求位址和控制器中​

​@RequestMapping​

​​注解的​

​value​

​屬性值進行比對,若比對成功,該注解所辨別的控制器方法就是處理請求的方法。處理請求的方法需要傳回一個字元串類型的視圖名稱,該視圖名稱會被視圖解析器解析,加上字首和字尾組成視圖的路徑,通過Thymeleaf對視圖進行渲染,最終轉發到視圖所對應頁面。

【3】CharacterEncodingFilter

Servlet Filter 允許為請求指定一個字元編碼。這很有用,因為目前浏覽器通常不設定字元編碼,即使在HTML頁面或表單中指定了字元編碼。

如果請求尚未指定編碼,則此Filter可以應用其編碼,或者在任何情況下強制執行此Filter的編碼(​

​“forceEncoding”=“true”​

​)。在後一種情況下,編碼也将作為預設響應編碼應用(盡管這通常會被視圖中設定的完整内容類型覆寫)。

<filter>
   <filter-name>CharacterEncodingFilter</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
   </init-param>
   <init-param>
       <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>      

解決GET請求亂碼的一種方式是可以修改​

​Tomcat的server.xml在Connector​

​​标簽裡面配置​

​URIEncoding="UTF-8"​

​,但是隻是針對目前Tomcat哦。

原生Servlet中解決POST亂碼的一種方式是​

​request.setCharacterEncoding("UTF-8");​

​​但是在SpringMVC中不好用。因為DispatchServlet在目标方法前從request中擷取了參數,故而在目标方法裡面再使用​

​request.setCharacterEncoding("UTF-8");​

​不生效。

同時注冊CharacterEncodingFilter與HiddenHttpMethodFilter次序

在web.xml中注冊時,必須先注冊​

​CharacterEncodingFilter​

​​,再注冊​

​HiddenHttpMethodFilter​

​。原因如下:

  • 在​

    ​CharacterEncodingFilter​

    ​​ 中通過​

    ​request.setCharacterEncoding(encoding)​

    ​​ 方法設定字

    符集的。

  • ​request.setCharacterEncoding(encoding)​

    ​ 方法要求前面不能有任何擷取請求參數的操作
  • 而 HiddenHttpMethodFilter 恰恰有一個擷取請求方式的操作:​

    ​String paramValue = request.getParameter(this.methodParam);​

【4】域對象共享資料

① 使用ServletAPI向request域對象共享資料

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
  request.setAttribute("testScope", "hello,servletAPI");
  return "success";
}      

② 使用ModelAndView向request域對象共享資料

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
  /**
  * ModelAndView有Model和View的功能
  * Model主要用于向請求域共享資料
  * View主要用于設定視圖,實作頁面跳轉
  */
  ModelAndView mav = new ModelAndView();
  //向請求域共享資料
  mav.addObject("testScope", "hello,ModelAndView");
  //設定視圖,實作頁面跳轉
  mav.setViewName("success");
  return mav;
}      

③ 使用Model向request域對象共享資料

@RequestMapping("/testModel")
public String testModel(Model model){
  model.addAttribute("testScope", "hello,Model");
  return "success";
}      

④ 使用map向request域對象共享資料

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
  map.put("testScope", "hello,Map");
  return "success";
}      

⑤ 使用ModelMap向request域對象共享資料

@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
  modelMap.addAttribute("testScope", "hello,ModelMap");
  return "success";
}      

⑥ Model、ModelMap、Map的關系

Model、ModelMap、Map類型的參數其實本質上都是 BindingAwareModelMap 類型的的執行個體。

public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}      
SpringMVC工程基礎入門實踐

⑦ 向session域共享資料

@RequestMapping("/testSession")
public String testSession(HttpSession session){
  session.setAttribute("testSessionScope", "hello,session");
  return "success";
}      

⑧ 向application域共享資料

@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
  ServletContext application = session.getServletContext();
  application.setAttribute("testApplicationScope", "hello,application");
  return "success";
}      

【5】SpringMVC的視圖

SpringMVC工程基礎入門實踐

SpringMVC中的視圖是View接口,視圖的作用渲染資料,将模型Model中的資料展示給使用者。SpringMVC視圖的種類很多,預設有轉發視圖和重定向視圖。

① 轉發視圖

當控制器方法中所設定的視圖名稱​

​沒有任何字首​

​​時,此時的視圖名稱會被SpringMVC配置檔案中所配置

的視圖解析器解析,​​

​視圖名稱拼接視圖字首和視圖字尾所得到的最終路徑​

​,會通過轉發的方式實作跳轉。

@RequestMapping("/")
  public String index(){
      return "index";
  }      

若使用的視圖技術為Thymeleaf,在SpringMVC的配置檔案中配置了Thymeleaf的視圖解析器,由此視圖解析器解析之後所得到的是​

​ThymeleafView​

​​。

SpringMVC工程基礎入門實踐

SpringMVC中預設的轉發視圖是​

​InternalResourceView​

​​。當控制器方法中所設定的視圖名稱以​

​"forward:"​

​​為字首時,建立​

​InternalResourceView​

​​視圖,此時的視圖名稱不會被SpringMVC配置檔案中所配置的視圖解析器解析,而是會将字首​

​"forward:"​

​​去掉,剩餘部分作為最終路徑通過轉發的方式實作跳轉。當工程引入jstl的依賴,轉發視圖會自動轉換為​

​JstlView​

​​。

SpringMVC工程基礎入門實踐

② 重定向視圖

SpringMVC中預設的重定向視圖是RedirectView。當控制器方法中所設定的視圖名稱以​

​"redirect:"​

​​為字首時,建立RedirectView視圖,此時的視圖名稱不會被SpringMVC配置檔案中所配置的視圖解析器解析,而是會将字首​

​"redirect:"​

​去掉,剩餘部分作為最終路徑通過重定向的方式實作跳轉。

@RequestMapping("/testRedirect")
public String testRedirect(){
  return "redirect:/testParam";
}      
SpringMVC工程基礎入門實踐

③ 視圖控制器view-controller

<!--
path:設定處理的請求位址
view-name:設定請求位址所對應的視圖名稱
-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>      

繼續閱讀