天天看點

Spring MVC【入門】就這一篇!

MVC 設計概述

在早期 Java Web 的開發中,統一把顯示層、控制層、資料層的操作全部交給 JSP 或者 JavaBean 來進行處理,我們稱之為 Model1:

  • 出現的弊端:
  • JSP 和 Java Bean 之間嚴重耦合,Java 代碼和 HTML 代碼也耦合在了一起
  • 要求開發者不僅要掌握 Java ,還要有高超的前端水準
  • 前端和後端互相依賴,前端需要等待後端完成,後端也依賴前端完成,才能進行有效的測試
  • 代碼難以複用

正因為上面的種種弊端,是以很快這種方式就被 Servlet + JSP + Java Bean 所替代了,早期的 MVC 模型(Model2)就像下圖這樣:

首先使用者的請求會到達 Servlet,然後根據請求調用相應的 Java Bean,并把所有的顯示結果交給 JSP 去完成,這樣的模式我們就稱為 MVC 模式。

  • M 代表 模型(Model)

    模型是什麼呢? 模型就是資料,就是 dao,bean

  • V 代表 視圖(View)

    視圖是什麼呢? 就是網頁, JSP,用來展示模型中的資料

  • C 代表 控制器(controller)

    控制器是什麼? 控制器的作用就是把不同的資料(Model),顯示在不同的視圖(View)上,Servlet 扮演的就是這樣的角色。

擴充閱讀:Web開發模式

Spring MVC 的架構

為解決持久層中一直未處理好的資料庫事務的程式設計,又為了迎合 NoSQL 的強勢崛起,Spring MVC 給出了方案:

傳統的模型層被拆分為了業務層(Service)和資料通路層(DAO,Data Access Object)。在 Service 下可以通過 Spring 的聲明式事務操作資料通路層,而在業務層上還允許我們通路 NoSQL ,這樣就能夠滿足異軍突起的 NoSQL 的使用了,它可以大大提高網際網路系統的性能。

  • 特點:

    結構松散,幾乎可以在 Spring MVC 中使用各類視圖

    松耦合,各個子產品分離

    與 Spring 無縫內建

Hello Spring MVC

讓我們來寫一下我們的第一個 Spring MVC 程式:

第一步:在 IDEA 中建立 Spring MVC 項目

并且取名為 【HelloSpringMVC】,點選【Finish】:

IDEA 會自動幫我們下載下傳好必要的 jar 包,并且為我們建立好一些預設的目錄和檔案,建立好以後項目結構如下:

第二步:修改 web.xml

我們打開 web.xml ,按照下圖完成修改:

<url-pattern>

元素的值改為 / ,表示要攔截所有的請求,并交由Spring MVC的背景控制器來處理,改完之後:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
           

第三步:編輯 dispatcher-servlet.xml

這個檔案名的開頭 dispatcher 與上面 web.xml 中的

<servlet-name>

元素配置的 dispatcher 對應,這是 Spring MVC 的映射配置檔案(xxx-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">

    <bean id="simpleUrlHandlerMapping"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <!-- /hello 路徑的請求交給 id 為 helloController 的控制器處理-->
                <prop key="/hello">helloController</prop>
            </props>
        </property>
    </bean>
    <bean id="helloController" class="controller.HelloController"></bean>
</beans>
           

第四步:編寫 HelloController

在 Package【controller】下建立 【HelloController】類,并實作 org.springframework.web.servlet.mvc.Controller 接口:

package controller;

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

public class HelloController implements Controller{
	@Override
	public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
		return null;
	}
}
           
  • 出現了問題: javax.servlet 包找不到
  • 解決: 将本地 Tomcat 伺服器的目錄下【lib】檔案夾下的 servlet-api.jar 包拷貝到工程【lib】檔案夾下,添加依賴

Spring MVC 通過 ModelAndView 對象把模型和視圖結合在一起

ModelAndView mav = new ModelAndView("index.jsp");
mav.addObject("message", "Hello Spring MVC");
           

這裡表示視圖的是index.jsp

模型資料的是 message,内容是 “Hello Spring MVC”

package controller;

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

public class HelloController implements Controller {

	public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
		ModelAndView mav = new ModelAndView("index.jsp");
		mav.addObject("message", "Hello Spring MVC");
		return mav;
	}
}
           

第五步:準備 index.jsp

将 index.jsp 的内容修改為:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<h1>${message}</h1>
           

内容很簡單,用El表達式顯示 message 的内容。

第六步:部署 Tomcat 及相關環境

在【Run】菜單項下找到【Edit Configurations】

配置 Tomcat 環境:

選擇好本地的 Tomcat 伺服器,并改好名字:

在 Deployment 标簽頁下完成如下操作:

點選 OK 就好了,我們點選右上角的三角形将 Tomcat 伺服器運作起來。

  • 出現的問題: Tomcat 伺服器無法正常啟動
  • 原因: Tomcat 伺服器找不到相關的 jar 包
  • 解決方法: 将【lib】檔案夾整個剪貼到【WEB-INF】下,并重建立立依賴:

第七步:重新開機伺服器

重新開機伺服器,輸入位址:localhost/hello

參考資料:Spring MVC 教程(how2j.cn)

跟蹤 Spring MVC 的請求

每當使用者在 Web 浏覽器中點選連結或者送出表單的時候,請求就開始工作了,像是郵差一樣,從離開浏覽器開始到擷取響應傳回,它會經曆很多站點,在每一個站點都會留下一些資訊同時也會帶上其他資訊,下圖為 Spring MVC 的請求流程:

第一站:DispatcherServlet

從請求離開浏覽器以後,第一站到達的就是 DispatcherServlet,看名字這是一個 Servlet,通過 J2EE 的學習,我們知道 Servlet 可以攔截并處理 HTTP 請求,DispatcherServlet 會攔截所有的請求,并且将這些請求發送給 Spring MVC 控制器。

<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>
           
  • DispatcherServlet 的任務就是攔截請求發送給 Spring MVC 控制器。

第二站:處理器映射(HandlerMapping)

  • 問題:典型的應用程式中可能會有多個控制器,這些請求到底應該發給哪一個控制器呢?

是以 DispatcherServlet 會查詢一個或多個處理器映射來确定請求的下一站在哪裡,處理器映射會根據請求所攜帶的 URL 資訊來進行決策,例如上面的例子中,我們通過配置 simpleUrlHandlerMapping 來将 /hello 位址交給 helloController 處理:

<bean id="simpleUrlHandlerMapping"
      class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- /hello 路徑的請求交給 id 為 helloController 的控制器處理-->
            <prop key="/hello">helloController</prop>
        </props>
    </property>
</bean>
<bean id="helloController" class="controller.HelloController"></bean>
           

第三站:控制器

一旦選擇了合适的控制器, DispatcherServlet 會将請求發送給選中的控制器,到了控制器,請求會卸下其負載(使用者送出的請求)等待控制器處理完這些資訊:

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
	// 處理邏輯
    ....
}
           

第四站:傳回 DispatcherServlet

當控制器在完成邏輯處理後,通常會産生一些資訊,這些資訊就是需要傳回給使用者并在浏覽器上顯示的資訊,它們被稱為模型(Model)。僅僅傳回原始的資訊時不夠的——這些資訊需要以使用者友好的方式進行格式化,一般會是 HTML,是以,資訊需要發送給一個視圖(view),通常會是 JSP。

控制器所做的最後一件事就是将模型資料打包,并且表示出用于渲染輸出的視圖名(邏輯視圖名)。它接下來會将請求連同模型和視圖名發送回 DispatcherServlet。

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
	// 處理邏輯
    ....
    // 傳回給 DispatcherServlet
	return mav;
}
           

第五站:視圖解析器

這樣以來,控制器就不會和特定的視圖相耦合,傳遞給 DispatcherServlet 的視圖名并不直接表示某個特定的 JSP。(實際上,它甚至不能确定視圖就是 JSP)相反,它傳遞的僅僅是一個邏輯名稱,這個名稱将會用來查找産生結果的真正視圖。

DispatcherServlet 将會使用視圖解析器(view resolver)來将邏輯視圖名比對為一個特定的視圖實作,它可能是也可能不是 JSP

上面的例子是直接綁定到了 index.jsp 視圖

第六站:視圖

既然 DispatcherServlet 已經知道由哪個視圖渲染結果了,那請求的任務基本上也就完成了。

它的最後一站是視圖的實作,在這裡它傳遞模型資料,請求的任務也就完成了。視圖使用模型資料渲染出結果,這個輸出結果會通過響應對象傳遞給用戶端。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%>

<h1>${message}</h1>
           

使用注解配置 Spring MVC

上面我們已經對 Spring MVC 有了一定的了解,并且通過 XML 配置的方式建立了第一個 Spring MVC 程式,我們來看看基于注解應該怎麼完成上述程式的配置:

第一步:為 HelloController 添加注解

package controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController{

	@RequestMapping("/hello")
	public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
		ModelAndView mav = new ModelAndView("index.jsp");
		mav.addObject("message", "Hello Spring MVC");
		return mav;
	}
}
           

把實作的接口也給去掉。

  • 簡單解釋一下:
  • @Controller

    注解:

    很明顯,這個注解是用來聲明控制器的,但實際上這個注解對 Spring MVC 本身的影響并不大。(Spring 實戰說它僅僅是輔助實作元件掃描,可以用

    @Component

    注解代替,但我自己嘗試了一下并不行,因為上述例子沒有配置 JSP 視圖解析器我還自己配了一個仍沒有成功...)
  • @RequestMapping

    很顯然,這就表示路徑

    /hello

    會映射到該方法上

第二步:取消之前的 XML 注釋

在 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.xsd">

    <!--<bean id="simpleUrlHandlerMapping"-->
                                        <!--class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
    <!--<property name="mappings">-->
            <!--<props>-->
                <!--&lt;!&ndash; /hello 路徑的請求交給 id 為 helloController 的控制器處理&ndash;&gt;-->
                <!--<prop key="/hello">helloController</prop>-->
            <!--</props>-->
        <!--</property>-->
    <!--</bean>-->
    <!--<bean id="helloController" class="controller.HelloController"></bean>-->

    <!-- 掃描controller下的元件 -->
    <context:component-scan base-package="controller"/>
</beans>
           

第三步:重新開機伺服器

當配置完成,重新啟動伺服器,輸入

localhost/hello

位址仍然能看到效果:

@RequestMapping 注解細節

如果

@RequestMapping

作用在類上,那麼就相當于是給該類所有配置的映射位址前加上了一個位址,例如:

@Controller
@RequestMapping("/wmyskxz")
public class HelloController {
	@RequestMapping("/hello")
	public ModelAndView handleRequest(....) throws Exception {
		....
	}
}
           
  • 則通路位址:

    localhost/wmyskxz/hello

配置視圖解析器

還記得我們 Spring MVC 的請求流程嗎,視圖解析器負責定位視圖,它接受一個由 DispaterServlet 傳遞過來的邏輯視圖名來比對一個特定的視圖。

  • 需求: 有一些頁面我們不希望使用者使用者直接通路到,例如有重要資料的頁面,例如有模型資料支撐的頁面。
  • 造成的問題:

    我們可以在【web】根目錄下放置一個【test.jsp】模拟一個重要資料的頁面,我們什麼都不用做,重新啟動伺服器,網頁中輸入

    localhost/test.jsp

    就能夠直接通路到了,這會造成資料洩露...

    另外我們可以直接輸入

    localhost/index.jsp

    試試,根據我們上面的程式,這會是一個空白的頁面,因為并沒有擷取到

    ${message}

    參數就直接通路了,這會影響使用者體驗

解決方案

我們将我們的 JSP 檔案配置在【WEB-INF】檔案夾中的【page】檔案夾下,【WEB-INF】是 Java Web 中預設的安全目錄,是不允許使用者直接通路的(也就是你說你通過

localhost/WEB-INF/

這樣的方式是永遠通路不到的)

但是我們需要将這告訴給視圖解析器,我們在 dispatcher-servlet.xml 檔案中做如下配置:

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/" />
    <property name="suffix" value=".jsp" />
</bean>
           

這裡配置了一個 Spring MVC 内置的一個視圖解析器,該解析器是遵循着一種約定:會在視圖名上添加字首和字尾,進而确定一個 Web 應用中視圖資源的實體路徑的。讓我們實際來看看效果:

第一步:修改 HelloController

我們将代碼修改一下:

第二步:配置視圖解析器:

按照上述的配置,完成:

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

    <!--<bean id="simpleUrlHandlerMapping"-->
                                        <!--class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
    <!--<property name="mappings">-->
            <!--<props>-->
                <!--&lt;!&ndash; /hello 路徑的請求交給 id 為 helloController 的控制器處理&ndash;&gt;-->
                <!--<prop key="/hello">helloController</prop>-->
            <!--</props>-->
        <!--</property>-->
    <!--</bean>-->
    <!--<bean id="helloController" class="controller.HelloController"></bean>-->

    <!-- 掃描controller下的元件 -->
    <context:component-scan base-package="controller"/>
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
           

第三步:剪貼 index.jsp 檔案

在【WEB-INF】檔案夾下建立一個【page】檔案夾,并将【index.jsp】檔案剪貼到裡面:

第四步:更新資源重新開機伺服器

通路

localhost/hello

路徑,看到正确效果:

  • 原理:

我們傳入的邏輯視圖名為 index ,再加上 “

/WEB-INF/page/

” 字首和 “

.jsp

” 字尾,就能确定實體視圖的路徑了,這樣我們以後就可以将所有的視圖放入【page】檔案夾下了!

  • 注意:此時的配置僅是 dispatcher-servlet.xml 下的

控制器接收請求資料

使用控制器接收參數往往是 Spring MVC 開發業務邏輯的第一步,為探索 Spring MVC 的傳參方式,為此我們先來建立一個簡單的表單用于送出資料:

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
<html>
<head>
    <meta charset="utf-8">
    <title>Spring MVC 傳參方式</title>
</head>
<body>
<form action="/param" role="form">
    使用者名:<input type="text" name="userName"><br/>
    密碼:<input type="text" name="password"><br/>
    <input type="submit" value="提  交">
</form>
</body>
</html>
           

醜就醜點兒吧,我們就是來測試一下:

使用 Servlet 原生 API 實作:

我們很容易知道,表單會送出到

/param

這個目錄,我們先來使用 Servlet 原生的 API 來看看能不能擷取到資料:

@RequestMapping("/param")
public ModelAndView getParam(HttpServletRequest request,
						 HttpServletResponse response) {
	String userName = request.getParameter("userName");
	String password = request.getParameter("password");

	System.out.println(userName);
	System.out.println(password);
	return null;
}
           

測試成功:

使用同名比對規則

我們可以把方法定義的形參名字設定成和前台傳入參數名一樣的方法,來擷取到資料(同名比對規則):

@RequestMapping("/param")
public ModelAndView getParam(String userName,
							 String password) {
	System.out.println(userName);
	System.out.println(password);
	return null;
}
           
  • 問題: 這樣又會和前台産生很強的耦合,這是我們不希望的
  • 解決: 使用

    @RequestParam("前台參數名")

    來注入:
  • @RequestParam

    注解細節:

    該注解有三個變量:

    value

    required

    defaultvalue

  • value

    :指定

    name

    屬性的名稱是什麼,

    value

    屬性都可以預設不寫
  • required

    :是否必須要有該參數,可以設定為【true】或者【false】
  • defaultvalue

    :設定預設值

使用模型傳參

  • 要求: 前台參數名字必須和模型中的字段名一樣

讓我們先來為我們的表單建立一個 User 模型:

package pojo;

public class User {
	
	String userName;
	String password;

	/* getter and setter */
}
           

然後測試仍然成功:

中文亂碼問題

  • 注意: 跟 Servlet 中的一樣,該方法隻對 POST 方法有效(因為是直接處理的 request)

我們可以通過配置 Spring MVC 字元編碼過濾器來完成,在 web.xml 中添加:

<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>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
           

控制器回顯資料

通過上面,我們知道了怎麼接受請求資料,并能解決 POST 亂碼的問題,那麼我們怎麼回顯資料呢?為此我們在【page】下建立一個【test2.jsp】:

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" import="java.util.*" isELIgnored="false" %>
<html>
<head>
    <title>Spring MVC 資料回顯</title>
</head>
<body>
<h1>回顯資料:${message}</h1>
</body>
</html>
           

使用 Servlet 原生 API 來實作

我們先來測試一下 Servlet 原生的 API 是否能完成這個任務:

@RequestMapping("/value")
public ModelAndView handleRequest(HttpServletRequest request,
								  HttpServletResponse response) {
	request.setAttribute("message","成功!");
	return new ModelAndView("test1");
}
           

在浏覽器位址欄中輸入:

localhost/value

測試

使用 Spring MVC 所提供的 ModelAndView 對象

使用 Model 對象

在 Spring MVC 中,我們通常都是使用這樣的方式來綁定資料,

  • 使用

    @ModelAttribute

@ModelAttribute
public void model(Model model) {
	model.addAttribute("message", "注解成功");
}

@RequestMapping("/value")
public String handleRequest() {
	return "test1";
}
           

這樣寫就會在通路控制器方法 handleRequest() 時,會首先調用 model() 方法将

message

添加進頁面參數中去,在視圖中可以直接調用,但是這樣寫會導緻該控制器所有的方法都會首先調用 model() 方法,但同樣的也很友善,因為可以加入各種各樣的資料。

用戶端跳轉

前面不管是位址

/hello

跳轉到 index.jsp 還是

/test

跳轉到 test.jsp,這些都是服務端的跳轉,也就是

request.getRequestDispatcher("位址").forward(request, response);

那我們如何進行用戶端跳轉呢?我們繼續在 HelloController 中編寫:

@RequestMapping("/hello")
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
	ModelAndView mav = new ModelAndView("index");
	mav.addObject("message", "Hello Spring MVC");
	return mav;
}

@RequestMapping("/jump")
public ModelAndView jump() {
	ModelAndView mav = new ModelAndView("redirect:/hello");
	return mav;
}
           

我們使用

redirect:/hello

就表示我們要跳轉到

/hello

這個路徑,我們重新開機伺服器,在位址欄中輸入:

localhost/jump

,會自動跳轉到

/hello

路徑下:

也可以這樣用:

@RequestMapping("/jump")
public String jump() {
	return "redirect: ./hello";
}
           

檔案上傳

我們先來回顧一下傳統的檔案上傳和下載下傳:這裡

我們再來看一下在 Spring MVC 中如何實作檔案的上傳和下載下傳

  • 注意: 需要先導入

    commons-io-1.3.2.jar

    commons-fileupload-1.2.1.jar

    兩個包

第一步:配置上傳解析器

在 dispatcher-servlet.xml 中新增一句:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
           

開啟對上傳功能的支援

第二步:編寫 JSP

檔案名為 upload.jsp,仍建立在【page】下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>測試檔案上傳</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="picture">
    <input type="submit" value="上 傳">
</form>
</body>
</html>
           

第三步:編寫控制器

在 Package【controller】下建立【UploadController】類:

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class UploadController {

	@RequestMapping("/upload")
	public void upload(@RequestParam("picture") MultipartFile picture) throws Exception {
		System.out.println(picture.getOriginalFilename());
	}

	@RequestMapping("/test2")
	public ModelAndView upload() {
		return new ModelAndView("upload");
	}

}
           

第四步:測試

localhost/test2

,選擇檔案點選上傳,測試成功:

參考資料:

  • 《Java EE 網際網路輕量級架構整合開發》
  • 《Spring 實戰》
  • How2j Spring MVC 系列教程
  • 全能的百度和萬能的大腦

歡迎轉載,轉載請注明出處!

簡書ID:@我沒有三顆心髒

github:wmyskxz

歡迎關注公衆微信号:wmyskxz_javaweb

分享自己的Java Web學習之路以及各種Java學習資料

繼續閱讀