- Spring MVC是基于Model 2实现的技术框架,Model 2是经典的MVC模型在web应用中的变体。
- model 1的开发模式是:jsp+javabean的模式,它的核心是jsp页面。
- model 2的开发模式是:jsp+servlet+javabean的模式。
一、运行原理
- 用户发起请求后,由前端控制器DispatcherServlet接受用户请求响应
- 然后前端可控制性请求查找Handler,处理器映射器HandleMapper收到请求后通过xml或者注解,根据url找到对应的Handler(也就是Controller),找到之后前端控制器请求处理器适配器去执行Handler
- 处理器适配器调用处理器Handler的方法执行,返回ModelAndView
- 处理器适配器拿到ModelAndView后返回给前端控制器,前端控制器拿到ModelAndView后请求视图解析器去解析
- 解析完成之后将View返回给前端控制器,前端控制器将View进行渲染之后展示给用户。
- DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行, 统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
- HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件 方式,实现接口方式,注解方式等。
- HandlerAdapter:通过扩展处理器适配器,支持更多类型的处理器,调用处理器传 递参数等工作。
- ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、 freemarker、pdf、excel等。
二、开发步骤
1、引入依赖
- 添加依赖spring-webmvc,添加依赖后会添加八个jar包:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.2.RELEASE</version> </dependency>
2、配置web.xml
- 在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>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>
- 配置web.xml文件: 让所的/请求都交给DispatcherServlet,而DispatcherServlet里面需要配置一个contextConfigLocation,上下文配置路径,也就是SpringMVC的配置文件。如果没有显式地配置该属性,SpringMVC会在默认WEB-INF下去找[servlet-name]-servlet.xml文件
3、配置Spring MVC配置文件
有两种实现方式,一种是实现接口的方式,另一种是使用注解的方式。
-
实现接口:
- 第一个bean配置视图解析器,可以分别分别指定前缀与后缀,在虚拟视图前与后拼接字符串,去请求指定的资源。
- 第二个与第三个bean配置servlet,当用户请求指定url的时候就是去请求这个对应的类。使用name而不是id是因为id不能包含特殊字符。
- 最后一个mvc标签设置了默认的servlet-handler,用于请求静态资源。
<?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.controller.ProductInputController"/> <bean name="/ProductDetail" class="com.controller.ProductDetailController"/> <mvc:default-servlet-handler /> </beans>
-
配置SpringMVC的视图解析器:可以分别指定前缀和后缀
- prefix:控制器会在虚拟视图前拼接该字符串
- suffix:控制器会在虚拟视图后拼接该字符串
-
使用注解:
<?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>
最后一个标签指定使用注解,如果不加就扫描不到,访问非静态资源时就会出现404.
4、创建controller包及控制类
-
实现接口
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); } }
创建的新的controller类需要实现Controller接口然后重写handleRequest方法,这个方法接收HttpServletRequest与HttpServletResponse参数,返回一个ModelAndView,这个ModelAndView对象可以放需要转发到的虚拟的视图,还可以向request域中添加属性。
-
使用注解:
@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,这样在包扫描的时候就会扫描到,然后再每个方法前加上@RequestMapping注解,用于指定匹配的url,这个url必须全局唯一。
每个方法可以添加参数,也可以不加参数,既可以加一个参数,也可以加两个参数,Model、HttpSession、HttpServletRequest等类型的参数都可以作为形参。上面的两个方法返回值都是字符串,指定需要转发的页面。
-
常用内置对象
- strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length, trim, toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains, containsIgnoreCase等。
- numbers:数值格式化方法,常用的方法有:formatDecimal等。
- bools:布尔方法,常用的方法有:isTrue,isFalse等。
- arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等。
- lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等。
- maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等。
- dates:日期方法,常用的方法有:format,year,month,hour,createNow等。