<meta charset="utf-8">
Spring MVC基礎(chǔ)
Spring MVC是基于Model 2實(shí)現(xiàn)的技術(shù)框架扎唾,Model 2是經(jīng)典的MVC模型在web應(yīng)用中的變體每强。model 1的開發(fā)模式是:jsp+javabean的模式通贞,它的核心是jsp頁面寥闪。model 2的開發(fā)模式是:jsp+servlet+javabean的模式材失。
一敬飒、運(yùn)行原理
用戶發(fā)起請求后邪铲,由前端控制器DispatcherServlet接受用戶請求響應(yīng),然后前端可控制性請求查找Handler无拗,處理器映射器HandleMapper收到請求后通過xml或者注解带到,根據(jù)url找到對應(yīng)的Handler(也就是Controller),找到之后前端控制器請求處理器適配器去執(zhí)行Handler英染,處理器適配器調(diào)用處理器Handler的方法執(zhí)行揽惹,返回ModelAndView,處理器適配器拿到ModelAndView后返回給前端控制器四康,前端控制器拿到ModelAndView后請求視圖解析器去解析搪搏,解析完成之后將View返回給前端控制器,前端控制器將View進(jìn)行渲染之后展示給用戶箭养。具體流程如下圖所示:
二慕嚷、開發(fā)步驟
1、引入依賴
添加依賴spring-webmvc毕泌,添加依賴后會添加八個(gè)jar包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2喝检、配置web.xml
在web.xml中配置一個(gè)servlet與對應(yīng)的類:
<?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>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
init-param標(biāo)簽指定了上下文配置路徑,讓所有的請求都交給了DispatcherServlet撼泛,而DispatcherServlet里面需要配置一個(gè)contextConfigLocation挠说,上下文配置路徑,也就是我們的SpringMVC的配置文件愿题。如果沒有顯式地配置該屬性损俭,SpringMVC會在默認(rèn)WEB-INF下去找[servlet-name]-servlet.xml文件蛙奖。上面這種配置就是在resources目錄下尋找spring-mvc.xml。
3杆兵、配置Spring MVC配置文件
在這一步有兩種實(shí)現(xiàn)方式雁仲,一種是實(shí)現(xiàn)接口的方式,另一種是使用注解的方式琐脏,兩種方式配置的xml文件有所不同攒砖,但也有共同點(diǎn),比如配置視圖解析器
-
實(shí)現(xiàn)接口:
<?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: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 https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> <bean name="/ProductInput" class="com.qfedu.controller.ProductInputController"/> <bean name="/ProductDetail" class="com.qfedu.controller.ProductDetailController"/> <mvc:default-servlet-handler /> </beans>
第一個(gè)bean配置視圖解析器日裙,可以分別分別指定前綴與后綴吹艇,在虛擬視圖前與后拼接字符串,去請求指定的資源昂拂。第二個(gè)與第三個(gè)bean配置servlet受神,當(dāng)用戶請求指定url的時(shí)候就是去請求這個(gè)對應(yīng)的類。使用name而不是id是因?yàn)閕d不能包含特殊字符格侯。最后一個(gè)mvc標(biāo)簽設(shè)置了默認(rèn)的servlet-handler鼻听,用于請求靜態(tài)資源。
-
使用注解:
<?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:mvc="http://www.springframework.org/schema/mvc" 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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> </bean> <context:component-scan base-package="com.innovation"/> <mvc:default-servlet-handler /> <mvc:annotation-driven/> </beans>
最后一個(gè)標(biāo)簽指定使用注解养交,如果不加就掃描不到精算,訪問非靜態(tài)資源時(shí)就會出現(xiàn)404.
4、創(chuàng)建controller包及控制類
-
實(shí)現(xiàn)接口
package com.qfedu.controller; import com.qfedu.bean.Product; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProductDetailController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { String spid = httpServletRequest.getParameter("pid"); String pname = httpServletRequest.getParameter("pname"); String sprice = httpServletRequest.getParameter("price"); String image = httpServletRequest.getParameter("image"); int pid = spid == null||"".equals(spid.trim())?0:Integer.parseInt(spid); double price = sprice == null||"".equals(sprice.trim())?0.0:Double.parseDouble(sprice); Product p = new Product(pid,pname,price,image); //返回viewName碎连,將對象與對象名放入request域中 return new ModelAndView("product","product",p); } }
創(chuàng)建的新的controller類需要實(shí)現(xiàn)Controller接口然后重寫handleRequest方法灰羽,這個(gè)方法接收HttpServletRequest與HttpServletResponse參數(shù),返回一個(gè)ModelAndView鱼辙,這個(gè)ModelAndView對象可以放需要轉(zhuǎn)發(fā)到的虛擬的視圖廉嚼,還可以向request域中添加屬性。
-
使用注解:
npackage com.innovation.controller; import com.innovation.bean.Employee; import com.innovation.service.IEmployeeService; import com.innovation.service.impl.EmployeeServiceImpl; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.List; @Controller public class EmployeeController { private IEmployeeService service = new EmployeeServiceImpl(); @RequestMapping("/employees") public String getEmployeesPage(Model model){ List<Employee> list = service.getAllEmployees(); model.addAttribute("list",list); return "employees.jsp"; } @RequestMapping("/employeeInfo") public String getEmployById(HttpServletRequest request,Model model){ String eid = request.getParameter("eid"); int id = eid==null?-1:Integer.parseInt(eid); Employee e = service.getEmployeeById(id); model.addAttribute("employee",e); return "employeeInfo.jsp"; } }
使用注解的方式更為簡單倒戏,只需要在類名前加上@Controller怠噪,這樣在包掃描的時(shí)候就會掃描到,然后再每個(gè)方法前加上@RequestMapping注解杜跷,用于指定匹配的url傍念,這個(gè)url必須全局唯一。每個(gè)方法可以添加參數(shù)葛闷,也可以不加參數(shù)憋槐,既可以加一個(gè)參數(shù),也可以加兩個(gè)參數(shù)淑趾,Model阳仔、HttpSession、HttpServletRequest等類型的參數(shù)都可以作為形參扣泊。上面的兩個(gè)方法返回值都是字符串近范,指定需要轉(zhuǎn)發(fā)的頁面嘶摊。