1. 程式人生 > 實用技巧 >SpringMVC 學談 (第一章)

SpringMVC 學談 (第一章)

寫在前面:分享技術,共同進步,有不足請見諒,相關意見可評論告知 ~

程式設計路漫之遠兮,運架構式之簡化;
勸君專注案前事,亦是杯酒敬蒼生;

目錄

MVC概述:

MVC概念

MVC是模型(Model)、檢視

(View)、控制器(Controller)的簡寫,是一種軟體設計規範(架構模式)。是將業務邏輯、資料、顯示分離的方法來組織程式碼。主要作用是降低了檢視與業務邏輯間的雙向偶合

1、Model(模型):資料模型,提供要展示的資料,因此包含資料和行為,類比於領域模型或JavaBean元件(包含資料和行為),現在分為Value Object(資料Dao) 和 服務層(行為Service)。主要作用提供了模型資料查詢和模型資料的狀態更新等功能,包括資料和業務。

2、View(檢視):負責進行模型的展示,即為可視的使用者介面

3、Controller(控制器):接收使用者請求,委託給模型進行處理(狀態改變),處理完畢後把返回的模型資料返回給檢視,由檢視負責展示。也就是說控制器做了個排程員的工作。

典型的MVC為JSP + servlet + javabean的模式

執行流程與職責分析

使用者發請求 --> Servlet接收請求資料 --> 呼叫對應的業務邏輯方法

業務處理完畢 --> 返回更新後的資料給servlet --> servlet轉向到JSP由JSP來渲染頁面 ---> 響應給前端更新後的頁面


Model:模型,業務邏輯,儲存資料的狀態

View:檢視,顯示頁面

Controller:控制器 ,取得表單資料,呼叫業務邏輯,轉向指定的頁面


Servlet回顧

匯入pom依賴

<dependencies>
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.12</version>
   </dependency>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-webmvc</artifactId>
       <version>5.1.9.RELEASE</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.5</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet.jsp</groupId>
       <artifactId>jsp-api</artifactId>
       <version>2.2</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>jstl</artifactId>
       <version>1.2</version>
   </dependency>
</dependencies>

常規構建專案

父專案:新建普通maven專案(無新增模板)
子專案:建立一個Moudle:SpringMVC01-servlet , 並新增Web app的支援(新增框架支援)

1、匯入servlet 和 jsp 的 jar 依賴

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
</dependency>
<dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.2</version>
</dependency>

2、編寫一個Servlet類,用來處理使用者的請求

package com.kuang.servlet;

//實現Servlet介面
public class HelloServlet extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //取得引數
       String method = req.getParameter("method");
       if (method.equals("add")){
           req.getSession().setAttribute("msg","執行了add方法");
      }
       if (method.equals("delete")){
           req.getSession().setAttribute("msg","執行了delete方法");
      }
       //業務邏輯
       //檢視跳轉
       req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);
  }

   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req,resp);
  }
}

3、編寫test.jsp,在WEB-INF目錄下新建一個jsp的資料夾,新建test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Kuangshen</title>
</head>
<body>
${msg}
</body>
</html>

4、在web.xml中註冊Servlet

<?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">
   <servlet>
       <servlet-name>HelloServlet</servlet-name>
       <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>HelloServlet</servlet-name>
       <url-pattern>/user</url-pattern>
   </servlet-mapping>

</web-app>

配置Tomcat,並啟動測試

localhost:8080/user?method=add

localhost:8080/user?method=delete

SpringMVC啟航

概述

概念:Spring MVC是Spring Framework的一部分,是基於Java實現MVC的輕量級Web框架。

官方文件:

https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web

特點:

(1)輕量級,簡單易學,簡潔靈活

(2)高效 , 基於請求響應的MVC框架,與Spring無縫整合(使用SpringIoC和Aop)

(3)與Spring相容性好,無縫結合

(4)約定優於配置

(5)功能強大:RESTful、資料驗證、格式化、本地化、主題等


Spring的web框架圍繞DispatcherServlet [ 排程Servlet ] 設計。

DispatcherServlet的作用是將請求分發到不同的處理器。從Spring 2.5開始,使用Java 5或者以上版本的使用者可以採用基於註解形式進行開發

中心控制器



與其他框架類比
Spring MVC框架像許多其他MVC框架一樣, 以請求為驅動 , 圍繞一箇中心Servlet分派請求及提供其他功能,DispatcherServlet是一個實際的Servlet (它繼承自HttpServlet 基類)。

SpringMVC執行原理

實線表示SpringMVC框架提供的技術,虛線表示需要開發者實現。

當發起請求時被前置的控制器攔截到請求,根據請求引數生成代理請求,找到請求對應的實際控制器,控制器處理請求,建立資料模型,訪問資料庫,將模型響應給中心控制器,控制器使用模型與檢視渲染檢視結果,將結果返回給中心控制器,再將結果返回給請求者。DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。使用者發出請求,DispatcherServlet接收請求並攔截請求。

實列:若請求的url為 : http://localhost:8080/SpringMVC/hello
分解

http://localhost:8080伺服器域名

SpringMVC部署在伺服器上的web站點

hello表示控制器

結果:通過分析,如上url表示為:請求位於伺服器localhost:8080上的SpringMVC站點的hello控制器。

流程
HandlerMapping為處理器對映。DispatcherServlet呼叫HandlerMapping,HandlerMapping根據請求url查詢Handler。

HandlerExecution表示具體的Handler,其主要作用是根據url查詢控制器,如上url被查詢控制器為:hello。

HandlerExecution將解析後的資訊傳遞給DispatcherServlet,如解析控制器對映等。

HandlerAdapter表示處理器介面卡,其按照特定的規則去執行Handler。

Handler讓具體的Controller執行。

Controller將具體的執行資訊返回給HandlerAdapter,如ModelAndView

HandlerAdapter將檢視邏輯名或模型傳遞給DispatcherServlet

DispatcherServlet呼叫檢視解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯檢視名。

檢視解析器將解析的邏輯檢視名傳給DispatcherServlet

DispatcherServlet根據檢視解析器解析的檢視結果,呼叫具體的檢視。

最終檢視呈現給使用者。

SpringMVC編寫

配置版

1、配置web.xml , 註冊DispatcherServlet

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

   <!--1.註冊DispatcherServlet-->
   <servlet>
       <servlet-name>springmvc</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--關聯一個springmvc的配置檔案:【servlet-name】-servlet.xml-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!--啟動級別-1-->
       <load-on-startup>1</load-on-startup>
   </servlet>

   <!--/ 匹配所有的請求;(不包括.jsp)-->
   <!--/* 匹配所有的請求;(包括.jsp)-->
   <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

</web-app>

2、編寫SpringMVC 的 配置檔案!名稱:springmvc-servlet.xml : [servletname]-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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

5、新增 處理對映器

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

6、新增 處理器介面卡

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

7、新增 檢視解析器

<!--檢視解析器:DispatcherServlet給他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
   <!--字首-->
   <property name="prefix" value="/WEB-INF/jsp/"/>
   <!--字尾-->
   <property name="suffix" value=".jsp"/>
</bean>

8、編寫我們要操作業務Controller ,要麼實現Controller介面,要麼增加註解;需要返回一個ModelAndView,裝資料,封檢視;

package com.kuang.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//注意:這裡我們先匯入Controller介面
public class HelloController implements Controller {

   public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
       //ModelAndView 模型和檢視
       ModelAndView mv = new ModelAndView();

       //封裝物件,放在ModelAndView中。Model
       mv.addObject("msg","HelloSpringMVC!");
       //封裝要跳轉的檢視,放在ModelAndView中
       mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
       return mv;
  }
   
}

9、將自己的類交給SpringIOC容器,註冊bean

<!--Handler-->
<bean id="/hello" class="com.kuang.controller.HelloController"/>
10、寫要跳轉的jsp頁面,顯示ModelandView存放的資料,以及我們的正常頁面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>lzh</title>
</head>
<body>
${msg}
</body>
</html>

註解版(重要)

一、三大區域配置

pom.xml
springmvc-servlet.xml
web.xml

1、在pom.xml完善配置,防止Maven可能存在資源過濾的問題(固定)

<build>
   <resources>
       <resource>
           <directory>src/main/java</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
       <resource>
           <directory>src/main/resources</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
   </resources>
</build>

2、在pom.xml檔案引入相關的依賴:主要有Spring框架核心庫、Spring MVC、servlet , JSTL等。(已經在父依賴中)(固定)
3、配置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">

   <!--1.註冊servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--通過初始化引數指定SpringMVC配置檔案的位置,進行關聯-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- 啟動順序,數字越小,啟動越早 -->
       <load-on-startup>1</load-on-startup>
   </servlet>

   <!--所有請求都會被springmvc攔截 -->
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

</web-app>

總結
/ 和 /* 的區別:< url-pattern > / </ url-pattern > 不會匹配到.jsp, 只針對我們編寫的請求;即:.jsp 不會進入spring的 DispatcherServlet類 。< url-pattern > /* </ url-pattern > 會匹配 .jsp,會出現返回 jsp檢視 時再次進入spring的DispatcherServlet 類,導致找不到對應的controller所以報404錯。
注意事項
(1)注意web.xml版本問題,要最新版!
(2)註冊DispatcherServlet
(3)關聯SpringMVC的配置檔案
(4)啟動級別為1
(5)對映路徑為 / 【不要用/
,會404】

4、新增Spring MVC配置檔案
在resource目錄下新增springmvc-servlet.xml配置檔案,配置的形式與Spring容器配置基本類似,為了支援基於註解的IOC,設定了自動掃描包的功能,具體配置資訊如下:

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

   <!-- 自動掃描包,讓指定包下的註解生效,由IOC容器統一管理 -->
   <context:component-scan base-package="com.kuang.controller"/>
   <!-- 讓Spring MVC不處理靜態資源 -->
   <mvc:default-servlet-handler />
   <!--
   支援mvc註解驅動
       在spring中一般採用@RequestMapping註解來完成對映關係
       要想使@RequestMapping註解生效
       必須向上下文中註冊DefaultAnnotationHandlerMapping
       和一個AnnotationMethodHandlerAdapter例項
       這兩個例項分別在類級別和方法級別處理。
       而annotation-driven配置幫助我們自動完成上述兩個例項的注入。
    -->
   <mvc:annotation-driven />

   <!-- 檢視解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
         id="internalResourceViewResolver">
       <!-- 字首 -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- 字尾 -->
       <property name="suffix" value=".jsp" />
   </bean>

</beans>

關鍵點再敘
(1)自動掃描包
(2)過濾靜態資源(css,html,mp3)
(3)支援mvc註解驅動
(4)檢視解析器
在檢視解析器中我們把所有的檢視都存放在/WEB-INF/目錄下,這樣可以保證檢視安全,因為這個目錄下的檔案,客戶端不能直接訪問。

二、建立Controller

1、編寫一個Java控制類:com.kuang.controller.HelloController , 注意編碼規範

package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;



@Controller
@RequestMapping("/HelloController")
public class HelloController {

   //真實訪問地址 : 專案名/HelloController/hello
   @RequestMapping("/hello")
   public String sayHello(Model model){
       //向模型中新增屬性msg與值,可以在JSP頁面中取出並渲染
       model.addAttribute("msg","hello,SpringMVC");
       //web-inf/jsp/hello.jsp
       return "hello";
  }
}

@Controller是為了讓Spring IOC容器初始化時自動掃描到;

@RequestMapping是為了對映請求路徑,這裡因為類與方法上都有對映所以訪問時應該是/HelloController/hello;

真實訪問地址 : 專案名/HelloController/hello

方法中宣告Model型別的引數是為了把Action中的資料帶到檢視中;

方法返回的結果是檢視的名稱hello,加上配置檔案中的前後綴變成WEB-INF/jsp/hello.jsp。

2、建立檢視層

在WEB-INF/ jsp目錄中建立hello.jsp , 檢視可以直接取出並展示從Controller帶回的資訊;

可以通過EL表示取出Model中存放的值,或者物件;

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>SpringMVC</title>
</head>
<body>
${msg}
</body>
</html>

8、配置Tomcat執行
配置Tomcat , 開啟伺服器 , 訪問 對應的請求路徑!

常見錯誤與異常

①右鍵無法建立java類

解決在目錄結構中進行設定

②servlet-class 中路徑報紅問題

<servlet-name > 可以自定義,但是要唯一

<servlet-class>servlet的完全限定名=包名+類名,用來找到class,生成需要的物件;檢查是否寫錯的方法,按住Ctrl+滑鼠放於限定名上,如果連線說明可以找到;

<servlet-name>和servlet標籤中的servlet-name要一致;

<url-pattern>這個名稱是用來訪問名稱,請求路徑;


解法:直接重新新建一個模板

③ artifact deployment 錯誤

Artifact Springmvc02-mvc:war exploded: Error during artifact deployment. See server log for details.

(1)web.xml 等配置檔案,配置錯誤

(2)編輯tomcat 配置

(3)專案結構

④程式碼未出錯,訪問出現404


(1)檢視控制檯輸出,是否缺少了jar包。

(2)如果jar包存在,顯示無法輸出,就在IDEA的專案釋出中,新增lib依賴!
以下為步驟:


(3)重啟Tomcat

基於實戰中學習,學習快樂中成長
.
時間會回答成長,成長會回答夢想