Java web 之 Spring+Mybatis+Spring MVC框架整合(下)
前兩篇,我們主要講了聚合工程Maven的建立(通過Maven本地倉庫,集中管理我們專案中的jar包),子Maven Project ssm-web 繼承父Maven Project ssm-parent;ssm-web聚合專案中又建立了一個Maven Modulessm-web-test,打包方式為war包;以及Mybatis逆向工程的使用和Spring+Mybatis的整合,以及最後JUnit單元的除錯;SSM整合系列到現在,只剩下最後一個關鍵人物還沒有出場,那就是我們的 Spring MVC框架。
【聚合:很多節點合到一起的一個工程,但是每個節點不能獨立存在。】
Spring MVC
開始之前,我們先來看一下MVC(一種設計模式)的大致流程圖:
使用者發出請求給控制器,控制器決定去呼叫哪個模型,模型中有不同的業務邏輯,然後Model層返回相應的資料給控制器,控制器呼叫檢視,進行檢視渲染和組織資料,最後,將呈現好的介面和資料返回給我們使用者。
ok,以上是講前預熱,Now,我們開始我們的Spring MVC框架之旅。
首先,我們看下,目前我們的專案目錄結構:
配置spring-MVC.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:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置包掃描器 -->
<context:component-scan base-package="com.appleyk.controller"></context:component-scan>
<!-- 配置註解驅動 -->
<mvc:annotation-driven/>
<!-- 檢視解析器 定義跳轉的檔案的前後綴 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 新增靜態資源css、js對映檔案 -->
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
</beans>
上面,有幾個地方需要注意一下,下圖均已標註:
配置好MVC後,我們需要再配置一下整個專案的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>ssm-web-test</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 初始化Spring容器 +Spring和Mybatis的配置檔案-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mybatis/spring-mybatis.xml</param-value>
</context-param>
<!-- Spring監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring記憶體溢位監聽器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- Spring MVC的前端控制器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<!-- DispatcherServlet:中央控制器,把請求給轉發到具體的控制類 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必須的, 如果不配置contextConfigLocation, spring-MVC的配置檔案預設在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC/spring-MVC.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>
<!-- 解決post亂碼 -->
<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>
</web-app>
上面有幾個需要注意的敵法,如下圖標註:
其他倒沒什麼,好了,到這裡,我們的Spring MVC框架也整合進專案中了,我們跑一下整個專案,看下我們改動web.xml後,是否影響了我們整個web專案的走向:
小插曲(spring-MVC.xml的路徑寫錯了):
所以,配置檔案裡面,涉及路徑的地方,一定要檢查檢查再檢查,這裡,應該是
springMVC/spring-MVC.xml
上述的web.xml裡面,我已經更改了錯誤。改後,我們再次執行一下我們的web專案:
Good,我們SSM框架整合後的專案正常執行,最後看一眼index.jsp頁面,真的是最後一眼:
到這,先別急著興奮,因為我們還差一個重要的環節,那就是測試我們的Spring MVC框架,怎麼測,請繼續往下看:
我們想實現這樣一個功能,瀏覽器中輸入一個url請求,格式為/user/username,然後,我們將這個url中的username傳遞到一個jsp頁面進行歡迎展示:
(1)、怎麼跳到這個jsp頁面呢?
當然是使用@controller註解的方式,return jsp,當然我們的spring-MVC.xml中已經給我們配置好了檢視解析器的路徑(/WEB-INF/views/),我們這裡只需要返回一個包含jsp檔案的名字就行。
(2)、怎麼將這個username的值傳遞給jsp頁面呢?
這裡我們使用ModelAndView類實現,一看就知道,這個類含兩個部分,一個是資料部分,一個是檢視,因此,我們讓控制器Controller返回一個ModelAndView物件,該物件同時包含了要跳轉的頁面showUser和要傳遞的資料username
好了,我們開始,走一遍Controller-->Model-->View,測試一下Spring MVC:
1、在/WEB-INF/views/下面,新建一個jsp檔案,取名,showUser.jsp:
目前,showUser.jsp還未有任何內容輸出,我們放到後面
2、在com.appleyk.controller包下面新增一個java檔案UserController.java:
package com.appleyk.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UserController {
@RequestMapping("/user/{userName}")
public ModelAndView Hello(@PathVariable String userName){
ModelAndView mad = new ModelAndView("showUser");
//將資料存入modelMap
mad.addObject("message", userName);
return mad;
}
}
上面一個"showUser",就能指向對應的jsp檔案,有圖有真相:
控制器的類我們寫好了,現在差一個jsp前臺頁面展示,我們改一下我們的
showUser.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>appleyk的CSDN</title>
</head>
<body>
親愛的${requestScope.userName},歡迎你!
</body>
</html>
我們用requestScope(表示變數能在本次請求中使用)拿到mad物件中的userName
Controller我們寫好了,View我們也寫好了,現在就是Model,我們還沒有提供,這個資料來自於url請求中的userName,因此,我們需要先執行專案:
九月 01, 2017 1:39:32 下午 org.springframework.web.servlet.DispatcherServlet initServletBean
資訊: FrameworkServlet 'springMVC': initialization completed in 1219 ms
九月 01, 2017 1:39:32 下午 org.apache.coyote.AbstractProtocol start
資訊: Starting ProtocolHandler ["http-bio-8080"]
tomcat啟動成功,然後我們開啟瀏覽器,輸入:http://localhost:8080/user/appleyk
我們多試幾個:
我們依然使用url地址請求的方式
修改下UserController.java:
package com.appleyk.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.appleyk.pojo.User;
import com.appleyk.service.UserService;
@Controller
public class UserController {
@RequestMapping("/user/{userName}")
public ModelAndView Hello(@PathVariable String userName){
ModelAndView mad = new ModelAndView("showUser");
//將資料存入modelMap
mad.addObject("message", userName);
return mad;
}
@Autowired
private UserService userservice;
@RequestMapping("/user/id/{userID}")
@ResponseBody
public User getUserById(@PathVariable int userID){
User user =userservice.getUserById(userID);
return user;
}
}
需要解釋的地方下圖標註:
我們執行專案後,瀏覽器輸入http://localhost:8080/user/id/1:
我們可以找一下UserMapper.class所在的位置:
我們為ssm-web-test的pom.xml新增如下內容:
<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>
需要注意的地方下圖標註:
注意增加解決XXXMapper.xml不自動關聯的內容 在什麼位置上。好了,我們重新啟動一下我們的web專案:
九月 01, 2017 6:51:59 下午 org.springframework.web.servlet.DispatcherServlet initServletBean
資訊: FrameworkServlet 'springMVC': initialization completed in 1095 ms
九月 01, 2017 6:51:59 下午 org.apache.coyote.AbstractProtocol start
資訊: Starting ProtocolHandler ["http-bio-8080"]
我們驗證一下,我們的UserMapper.xml有沒有和我們的class放在一起:
ok,xml關聯的問題算是解決了。
我們重新在瀏覽器中輸入http://localhost:8080/user/id/2:
哈哈,有意思吧,跟闖關一樣,針對上面的問題,我們給我們的專案加個jar包依賴,在哪加? 當然是在ssm-web-test的pom.xml檔案里加:
增加的內容:
<!-- Jackson Json處理工具包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
圖片說明如下:
好了,到這,我們好像沒什麼要加的了,是嗎?我們再一次執行我們的專案:
資訊: FrameworkServlet 'springMVC': initialization completed in 1419 ms
九月 01, 2017 7:09:19 下午 org.apache.coyote.AbstractProtocol start
資訊: Starting ProtocolHandler ["http-bio-8080"]
九月 01, 2017 7:09:28 下午 com.alibaba.druid.pool.DruidDataSource info
資訊: {dataSource-1} inited
成功,我們重複瀏覽器的url請求操作:http://localhost:8080/user/id/1
我們再來試一下,其他人的資訊:
沒問題,很好,我們的Controller很完美的為我們返回了View+Model,我們再試試另外一個Controller行為(url請求):
非常好,到這,我們的SSM整合框架就全部完了,真是幾經週轉,吐血之作!雖然案例有點簡單,但是整合的過程卻一點不能馬虎,漏了哪個環節,專案即刻崩掉,你想想,如果你不熟練,一個bug都夠你折騰半天了。
最後附上整個專案的下載地址:專案下載
以及整個專案的圖文操作文件下載地址:我去,不等了,重新整理太慢了,去我的資源裡找
結束語:
不積跬步無以至千里,不積小流無以成江海,
程式人生的精彩需要堅持不懈地積累!!!