搭建 Spring MVC 框架踩坑記
出於出LCTF 2018 題目的原因,不得不自己搭建一個 Spring MVC 框架,雖然這只是一地步,但是踩了無數的坑,我在這裡簡單的記錄一下
0X01 建立專案
怎麼建立專案呢,建立什麼專案呢?這本身就是一個問題,後來在TG師傅的指點下,我最終選擇了使用 maven 的方式建立專案,因為這種方法使用 pom.xml 統一管理 jar 包,新增和管理都很方便
如圖所示:
這裡選擇 release 或者1.3 都可以,但是這其實是一個坑(這個坑後面會遇到 el 不支援的問題,我們後面再解決)
選擇好了以後,我們填寫一些基本的資訊
如圖所示:
groupid 是填寫類似於包名的內容,因為是本地專案,對我的意義不大,隨便寫一下,artifactld 是填寫你當前專案的名稱(這兩個選項待會我們還會遇見類似的在 pom.xml 裡面,我們待會介紹)
然後我們 next ,這裡 settings.xml 檔案預設是不存在在那個目錄下的,我們需要從 IDEA 的原始目錄中拷貝(IDEA 似乎自帶了兩個版本的 maven 如果你選擇了3 那就拷貝 3下面的 settings.xml 如果是二就以此類推),我的路徑是
D:\IDEA\IntelliJ IDEA 2018.2.4\plugins\maven\lib\maven3\conf\settiungs.xml
拷貝完以後,我們需要對這個檔案進行修改,因為我國的國情,原來的源是不能用的,我們要換國內源
在 <mirrors>
標籤裡面加上下面的語句
<id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
然後我們就下一步下一步,然後就靜靜等待專案框架載入完畢
0X02 配置 pom.xml
完畢以後我們就能修改 pom.xml 新增依賴,這裡指的就是下載一些必要的 jar 包
以下是我新增進去的內容
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>javax/servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>javax/servlet</groupId> <artifactId>jstl</artifactId> <version>1.0.6</version> </dependency>
這裡面的命名規則是什麼?
groupid 就是這個 Jar 所在的遠端的包的名字
artifactId 就是這個包自己的名字
version 就是版本
這裡我推薦一個網站,能清楚地查詢這些資訊
ofollow,noindex">https://mvnrepository.com
補充一點:
如果想包隨著 pom.xml 實時更新的話,可以在 File->settings->Build.Execution,Deployment->Build Tools-> Maven 裡面選擇 Always update snapashots
0X03 新增框架依賴
到剛剛為止我們只是簡單地建立了一個專案,是不是感覺和 spring 一點關係都沒有,沒錯!於是我們現在要新增框架依賴
右鍵我們的專案,選擇 add framework support
如圖所示:
選擇 Spring 在選擇 Spring MVC
如圖所示:
這裡注意兩點:
(1)要勾選那個自動建立配置檔案的選項(這個選項在選擇 Spring 的時候出現,但是選擇 Spring MVC 的時候沒有)
(2)如果框架選項裡面沒有 Spring ,那估計是在你的 project structor 裡面 的 modules 裡面配置了一個 spring 這可能是由於載入依賴的時候自動弄得,我們要手動刪除
如圖所示:
新增完框架依賴的目錄結構如圖:
框起來的部分就是他自動生成的配置檔案
0X04 完善目錄結構
我們一般在 WEB-INF 裡面新增的是 靜態檔案已經 jsp 檢視檔案,main 裡面新增一個叫做 java的 資原始檔夾用來放控制器,再新增一個 resources 作為資原始檔夾,再在 src 同級建一個 target 作為匯出目錄
如圖所示:
但是建立完畢以後我們發現,我們沒法再 java 資料夾中建立 class 或者 package ,這是因為我們還沒有給他們模型,我們要到 project structor 裡面去設定
如圖所示:
可以看到變了顏色,這就說明設定好了,我們就可以建立我們的專案了
0X05 寫專案
首先配置 web.xml 這是整個專案的配置檔案,我們最後要根據這個檔案的配置去找我們的 servlet
示例配置:
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
注意:
(1)其中 org.springframework.web.servlet.DispatcherServlet 非常重要,這個是 spring 框架的核心,就是他根據我們傳過來的名字 去尋找對應的 servlet 的配置檔案的
(2) 其中 / 表示根路徑的全部請求都用 dispatcher 這個 servlet 來接收
配置好了專案的配置檔案,我們再繼續配置 servlet 的配置檔案,這個檔案我們如果需要可以手動建立,命名規則就是 servlet名-servlet.xml ,因為初始化的時候 servlet 就叫 dispatcher 我們又選了自動生成,於是這個配置檔案已經有了,我們只需要修改,如果沒有,我們就要另外建立
dispatcher-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 http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.spring" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
其中
<context:component-scan base-package="com.spring" />
這部分是用來掃描包的,這個包就是我們應該在 java 資料夾中建立的包的前兩個節點,比如我們建立 com.spring.test 這個包,那我們就寫 com.spring
但是為了實現這個功能,光寫這個還不夠,我們還需要新增 beans 的內容,新增下面這兩行
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
然後我們需要指定我們的 檢視存在位置和字尾名
<property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" />
然後我們寫 controller
HelloController.java
package com.spring.test; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/hello") public class HelloController { @RequestMapping(method = RequestMethod.GET) public String printHello(ModelMap model){ model.addAttribute("message","Hello Spring MVC FrameWork"); return "hello"; } }
我們寫 jsp
hello.jsp
<%@ page contentType="text/html; charset=UTF-8" %> <html> <head> <title>Hello World</title> </head> <body> <h2>Hello, ${message}</h2> </body> </html>
坑點:
這裡面最坑的就是沒法解析 el 語句,因為我們下載的 web.xml 是 2.3 版本,以後的版本就支援了,所以為了解決這個問題我們需要修改一下 web.xml 的頭
註釋掉下面這一部分:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
修改一部分成下面這個樣子
<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">
然後再新增我們本地的 tomcat 專案就能運行了
0X06 擴充套件
如果我們想寫多個 servlet 的話,我們可以把 web.xml 改成下面這個樣子,這樣他會去找不同的 servlet 配置檔案實現不同的功能,而在這種情況下, controller 裡面的路由是基於 web.xml 的,比如 web.xml 配置 /error/* 的都去找 erorController ,然後 controller 寫的是 /error ,那我們最終訪問的時候就是 /error/error才能訪問到這個控制器
web.xml部分內容
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/right/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>error</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/error/*</url-pattern> </servlet-mapping>
0X07 總結
這篇文章只是搭建框架中的一點記錄防止忘記,以後還要深入學習。