SpringMVC學習筆記

SpringMVC簡介

Spring MVC是當前最優秀的MVC框架,自從Spring 2.5版本發佈後,由於支持註解配置,易用性有了大幅度的提高。Spring 3.0更加完善,實現了對Struts 2的超越。現在越來越多的開發團隊選擇了Spring MVC。
Spring3 MVC的優點:

1、Spring3 MVC使用簡單,學習成本低。學習難度小於Struts2,Struts2用不上的多餘功能太多。呵呵,當然這不是決定因素。

2、Spring3 MVC很容易就可以寫出性能優秀的程序,Struts2要處處小心纔可以寫出性能優秀的程序(指MVC部分)

3、Spring3 MVC的靈活是你無法想像的,Spring框架的擴展性有口皆碑,Spring3 MVC當然也不會落後,不會因使用了MVC框架而感到有任何的限制。

SpringMVC的maven配置:

<dependencyManagement>
	<dependencies>
	  <dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-framework-bom</artifactId>
	    <version>4.3.9.RELEASE</version>
	    <type>pom</type>
	    <scope>import</scope>
	  </dependency>
	</dependencies>
</dependencyManagement>

</dependencies>
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-webmvc</artifactId>
	</dependency>
</dependencies>

配置web.xml

<!-- 設置根上下文配置文件,與Spring Core容器有關 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:application-context.xml</param-value>
</context-param>

<!-- 註冊ContextLoaderListener-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 前端控制器:導演,註冊DispatcherServlet-->
<servlet>
    <servlet-name>servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <!-- 初始化參數 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-servlet.xml</param-value>
    </init-param>
</servlet>

<!-- 將註冊的DispatcherServlet映射到'/' -->
<servlet-mapping>
    <servlet-name>servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

配置視圖解析器:

<!--配置JSP視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>


<!-- 掃描包 control -->
<context:component-scan base-package="com.xpu.springmvc.control"/>
<!-- 啓用註解SpringMVC -->
<mvc:annotation-driven/>

一個示例Controller:

@Controller
@RequestMapping
public class IndexController {
    @RequestMapping(value = {"","/index"}, method = {RequestMethod.GET})
    public ModelAndView hello(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("welcome");//WEB-INFO/views/welcome.jsp
        return modelAndView;
    }
}

SpringMVC涉及的元素

在這裏插入圖片描述
模型-視圖-控制器(MVC模式)是一種非常經典的軟件架構模式,在UI框架和UI設計思路中扮演着非常重要的角色。從設計模式的角度來看,MVC模式是一種複合模式,它將多個設計模式在一種解決方案中結合起來,用來解決許多設計問題。MVC模式把用戶界面交互分拆到不同的三種角色中,使應用程序被分成三個核心部件: Model(模型)、View(視圖)、Control(控制器) ,它們各自處理自己的任務:

(1)模型:模型持有所有的數據、狀態和程序邏輯;模型獨立於視圖和控制器。
(2)視圖:用來呈現模型。視圖通常直接從模型中取得它需要顯示的狀態與數據。對於相同的信息可以有多個不同的顯示形式或視圖。
(3)控制器:位於視圖和模型中間,負責接受用戶的輸入,將輸入進行解析並反饋給模型,通常一個視圖具有一個控制器。
在這裏插入圖片描述
MVC模式將它們分離以提高系統的靈活性和複用性,不使用MVC模式,用戶界面設計往往將這些對象混在一起。 MVC模式實現了模型和視圖的分離,這帶來了幾個好處:
(1)一個模型提供不同的多個視圖表現形式,也能夠爲一個模型創建新的視圖而無須重寫模型。一旦模型的數據發生變化,模型將通知有關的視圖,每個視圖相應地刷新自己。
(2)模型可複用。因爲模型是獨立於視圖的,所以可以把一個模型獨立地移植到新的平臺工作。
(3)提高開發效率。在開發界面顯示部分時,你僅僅需要考慮的是如何佈局一個好的用戶界面;開發模型時,你僅僅要考慮的是業務邏輯和數據維護。這樣能使開發者專注於某一方面的開發,提高開發效率。

Servlet請求響應

Servlet對應的就是MVC框架模式中的控制器。Servlet負責在處理用戶請求和響應,其中數據的處理,頁面響應都是在Servlet裏面完成的。如下圖是Servlet請求響應示意圖:
在這裏插入圖片描述

SpringMVC請求響應

在這裏插入圖片描述
上面這張圖是SpringMVC請求處理的比較高層次的流程圖(隱含了更多細節),從圖上看它與Servlet處理請求的最大不同在於,它將視圖渲染,請求處理,模型創建分離了。即遵循了MVC框架模式的基本思想。
在這裏插入圖片描述
上圖是將高層次的流程圖細化到SpringMVC框架的具體實現上了,通過上圖我們可以看出,SpringMVC的請求響應經過的7個階段。其中2-6階段分別對應着SpringMVC框架中的幾個概念,分別是:前端控制器,處理映射器,控制器(處理器),視圖解析器,視圖。圖中綠色部分是用戶需要實現的內容

核心類的請求流程

在這裏插入圖片描述
第一步:(發起)發起請求到前端控制器(DispatcherServlet)
第二步:(查找)前端控制器請求HandlerMapping查找 Handler(可以根據xml配置、註解進行查找)
第三步:(返回)處理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping會把請求映射爲HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象,多個HandlerInterceptor攔截器對象),通過這種策略模式,很容易添加新的映射策略
第四步:(調用)前端控制器調用處理器適配器去執行Handler
第五步:(執行)處理器適配器HandlerAdapter將會根據適配的結果去執行Handler
第六步:(返回)Handler執行完成給適配器返回ModelAndView
第七步:(接收)處理器適配器向前端控制器返回ModelAndView (ModelAndView是SpringMVC框架的一個底層對象,包括 Model和view)
第八步:(解析)前端控制器請求視圖解析器去進行視圖解析 (根據邏輯視圖名解析成真正的視圖(jsp)),通過這種策略很容易更換其他視圖技術,只需要更改視圖解析器即可
第九步:(返回)視圖解析器向前端控制器返回View
第十步:(渲染)前端控制器進行視圖渲染 (視圖渲染將模型數據(在ModelAndView對象中)填充到request域)
第十一步:(響應)前端控制器向用戶響應結果

SpringMVC核心組件(後續補充的)

DispatcherServlet 控制器入口 負責分發請求 (前置控制器)
HandlerMapping 負責根據請求 找到對應的控制器(將請求映射到Handler)
Handler 後端控制器
HandlerInterceptor 處理器攔截器
HandlerExecution 處理器執行鏈
HandlerAdapter 處理器適配器
ViewResolver 視圖處理器 通過處理找到對應的頁面
ModelAndView 封裝數據信息和視圖信息的
Controller 真正處理請求的控制器

在這裏插入圖片描述

SpringMVC的xml配置方式

springmvc.xml配置如下

<!-- 配置HandlerMapping-->
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

        <!-- 配置Mapping -->
        <property name="mappings">
            <props>
                <prop key="/test">testHandler</prop>
            </props>
        </property>
    </bean>

    <!-- 配置Handler -->
    <bean id="testHandler" class="com.xpu.maven.MyHandler">
    </bean>

    <!-- 配置視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前綴-->
        <property name="prefix" value="/"></property>
        <!-- 配置後綴-->
        <property name="suffix" value=".jsp"></property>
    </bean>

web.xml配置

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <!--要使用的字符集,一般我們使用UTF-8(保險起見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>false</param-value>
    </init-param>
    <init-param>
      <!--是否強制設置response的編碼爲encoding,建議設置爲true,下面有關於這個參數的解釋-->
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置文件的路徑 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <!-- 這個配置servlet-mapping主要是爲了防止SpringMVC阻止了css文件請求 -->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

MyHandler.java

public class MyHandler implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
        HttpServletResponse httpServletResponse) throws Exception {
        //裝載模型數據
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "Tim");
        modelAndView.setViewName("show");
        return modelAndView;
    }

pom.xml

<properties>
    <encoding>UTF-8</encoding>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>


    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <!-- JSTL -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <!-- JSTL實現包 -->
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-impl</artifactId>
      <version>1.2.5</version>
    </dependency>
    <dependency>

      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.5.RELEASE</version>

    </dependency>

     <!-- 接收JSON數據shi時才使用 -->
     <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.8</version>
     </dependency>
  </dependencies>

SpringMVC的數據綁定

設計一個課程類Course和一些其他的JavaBean:

//課程類
public class Course {
    private int id;
    private String name;
    private double price;
}
//講師類
public class Author {
    private int id;
    private String name;
}
//課程類的集合類
public class CourseList {
    List<Course> list;
}
//課程類的集合類
public class CourseMap {
    private Map<String, Course> courseMap;
}

//課程類的集合類
public class CourseSet {
    private Set<Course> courseSet = new HashSet<>();

    public Set<Course> getCourseSet() {
        return courseSet;
    }

    public void setCourseSet(Set<Course> courseSet) {
        this.courseSet = courseSet;
    }
    
    //主要是爲了完成綁定
    public CourseSet(){
        courseSet.add(new Course());
        courseSet.add(new Course());
    }
}
/**
     * 基本類型
     */
    @RequestMapping(value = "/baseType")
    @ResponseBody
    public String baseType(@RequestParam(value = "id", required = false) int id){
        return "baseType id:"+id;
    }

    /**
     * 包裝類類型
     */
    @RequestMapping(value = "/packageType")
    @ResponseBody
    public String packageType(@RequestParam(value = "id") Integer id){
        return "packageType id:"+id;
    }
    
    /**
     * 數組類型
     */
    @RequestMapping(value = "/arrayType")
    @ResponseBody
    public String arrayType(String[] name){
        StringBuffer sb = new StringBuffer();
        for(String item: name){
            sb.append(item);
        }
        return sb.toString();
    }

    /**
     * 對象類型
     */
    @RequestMapping("/pojoType")
    public ModelAndView pojoType(Course course){
        ModelAndView view = new ModelAndView();
        courseDao.add(course);
        view.setViewName("index");
        view.addObject("courses", courseDao.getAll());

        return view;
    }

    /**
     * 對象list集合 
     */
    @RequestMapping("/listType")
    public ModelAndView listType(CourseList courseList){
        for(Course course : courseList.getList()){
            courseDao.add(course);
        }
        ModelAndView view = new ModelAndView();
        view.setViewName("index");
        view.addObject("courses", courseDao.getAll());
        return view;
    }

    /**
     * 對象map集合
     */
    @RequestMapping("/mapType")
    public ModelAndView mapType(CourseMap courseMap){
        //遍歷的是Key
        for(String key: courseMap.getCourseMap().keySet()){
            Course course = courseMap.getCourseMap().get(key);
            courseDao.add(course);
        }
        ModelAndView view = new ModelAndView();
        view.setViewName("index");
        view.addObject("courses", courseDao.getAll());
        return view;
    }

    /**
     * 對象set集合
     */
    @RequestMapping("/setType")
    public ModelAndView setType(CourseSet courseSet){
        //遍歷的是Key
        for(Course course: courseSet.getCourseSet()){
            courseDao.add(course);
        }
        ModelAndView view = new ModelAndView();
        view.setViewName("index");
        view.addObject("courses", courseDao.getAll());
        return view;
    }

    /**
     * JSON數據類型
     */
    @RequestMapping(value = "jsonType")
    @ResponseBody
    public Course jsonType(@RequestBody Course course){
        course.setPrice(course.getPrice()+100);
        return course;
    }

想要支持JSON數據格式:
springmvc.xml配置:

 <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

pom.xml

<!-- 接收JSON數據shi時才使用 -->
<dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.9.8</version>
</dependency>

需要注意的地方就是在接收爲Set對象集合的時候需要先:
在這裏插入圖片描述
在接收JSON數據的時候別忘了導入jar包,並且在springmvc.xml文件中配置!
級聯屬性的設定寫法:
在這裏插入圖片描述
還有在JSP中配置需要的配置項,方便EL表達式的使用!

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章