1.什么是SpringMvc?
Spring MVC是一个基于MVC(Model view Controller)模式的WEB框架,SpringMvc作为Spring中的一个模块,可以与Spring无缝集成,为应用程序中的Web层(表现层)提出的一套优秀的解决方案。它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化、等等)。
2.SpringMVC入门
(1)准备Spring环境: SpringMVC以Spring为核心,而Spring最核心的模块是IOC/DI容器,也就是SpringMVC的核心类和控制器要交给Spring管理。故项目中拥有Spring的运行环境.
(2) 准备SpringMVC jar包。
spring-webmvc-4.1.2.RELEASE.jar SpringMVC的jar文件。
spring-web-4.1.2.RELEASE.jar Spring对Web项目运行的支持。
(3)在web.xml中配置核心控制器 DispatcherServlet
这里是web.xml中的类容:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>springmvc</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 1.配置所有的请求均要到达核心控制器(dispatcherServlet)里去 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 启动springmvc的核心控制器的时候,就初始化加载springmvc的配置文件 --> <!-- 一般spring的配置文件都在放在src中或者resource文件中 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-mvc.xml</param-value> </init-param> <!-- DispatcherServlet启动比较耗时,在启动加载文件的时候就进行加载 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 支持UTF-8编码 --> <filter> <filter-name>characterEncoding</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>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
这里是 applicationContext-mvc.xml 类容:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 测试spring的环境:--> <bean id="mybean" class="java.util.Date"></bean> <!-- 开启Spring的注解的扫描:@Controller @Service @Repository @Component等 。默认存在--> <context:annotation-config /> <!-- 组件扫描路径 --> <context:component-scan base-package="com.gs"/> <!-- 开启springMVC的默认处理控制器 :处理静态资源 --> <mvc:default-servlet-handler /> <!-- 开启Springmvc的注解驱动:扫描@RequestMapping等注解 --> <mvc:annotation-driven/> <!-- springmvc的映射配置文件 --> <bean id="/hello1" class="com.gs.controller.HelloController"/> <bean id="/hello2" class="com.gs.controller.HandlerController"/> <!-- 配置文件上传解析器,id="multipartResolver",这个id不能乱写 设置一个maxUploadSize属性,就是上传文件的大小 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"> <value>2000000000</value> </property> </bean> </beans>
注意:
1.一般spring的配置文件applicationContext-mvc.xml 都在放在src中或者resource文件中,我们可以通过web.xml配置告诉SpringMVC我们的配置文件路径。

<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-mvc.xml</param-value> </init-param>
2. 如果我们把spring的配置文件放在 WEB-INF 文件夹中,不需要在web.xml中配置上面代码。 但是:
启动Tomcat服务器的时候会初始化SpringMVC中的DispatcherServlet,而这个DispatcherServlet会根据配置文件初始化Spring容器,默认配置文件路径为:/WEB-INF/<servlet-name>-servlet.xml。
故:把配置文件更名为springmvc-servlet.xml。
3. springmvc 控制器三种实现方式
① 实现Controller接口重写 handleRequest(HttpServletRequest req, HttpServletResponse resp)方法,返回值为 ModelAndView的对象,
并且还要将该类交给spring管理,配置的id的值就是该控制器的访问路径
public class HelloController implements Controller{ @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { //ModelAndView对象是springmvc控制器中的一个对象,用于封装数据模型和返回页面视图 ModelAndView mv = new ModelAndView(); mv.setViewName("/jsp/index.jsp"); return mv; } }
② 实现HttpRequestHandler接口 重写 handleRequest(HttpServletRequest req, HttpServletResponse resp)方法,没有返回值。
并且还要将该类交给spring管理,配置的id的值就是该控制器的访问路径
public class HandlerController implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //ModelAndView对象是springmvc控制器中的一个对象,用于封装数据模型和返回页面视图 ModelAndView mv = new ModelAndView(); mv.setViewName("/jsp/index.jsp"); } }
③ 普通类(pojo)和注解 @RequestMapping
首先要开启SprigMVC注解支持:
<!-- 开启Spring的注解的扫描:@Controller @Service @Repository @Component等 。默认存在--> <context:annotation-config /> <!-- 组件扫描路径 --> <context:component-scan base-package="com.gs"/> <!-- 开启springMVC的默认处理控制器 :处理静态资源 --> <mvc:default-servlet-handler /> <!-- 开启Springmvc的注解驱动:扫描@RequestMapping等注解 --> <mvc:annotation-driven/>
@Controller @RequestMapping("/pojo") public class PojoController { @RequestMapping("/add") public String addddddddddd(){ //访问该方法的具体路径是 /pojo/add System.out.println("进来了"); return "/jsp/index.jsp"; } }
4. springmvc 控制器常用操作:
接收页面传递参数、绑定数据到页面、返回json数据、文件上传、文件下载等
参数接收,首先要考虑乱码问题(Post请求才有问题)。然而springmvc框架本身没有处理请求编码,但是spring框架为我们提供了一个请求编码过滤器,我们在web.xml配置一个请求编码过滤器。
<!-- 支持UTF-8编码 --> <filter> <filter-name>characterEncoding</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>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1. 参数接收方式
① 通过控制器的执行方法参数来接收普通参数(表单的name属性对应的值要和传入的参数一致)
② 通过Domain模型对象来接收(表单的name属性对应的值要和模型对象的属性的名称一样)
③ 通过传统的HttpServletRequest接收
④ 通过url中的参数接收(restfull风格) @PathVariable("id")转换
2. 数据传递
就是Controller往前台(页面)传递数据
① 通过ModelAndView对象传递
② 通过Model对象传递
③ 通过request对象传递
④ 通过返回值传递
具体代码如下:
@Controller @RequestMapping("/user") public class UserController { // 1. 通过控制器的执行方法参数来接收普通参数 @RequestMapping("/add1") public String add111(@RequestParam("username") String name1, @RequestParam("age")String age1) { System.out.println( name1 +","+ age1 ); return "/jsp/index.jsp"; } // 2. 通过模型对象来接收(常用) ,形参中提供接受数据的模型对象. @RequestMapping("/add2") public String add222(User u) { System.out.println(u); return "/jsp/index.jsp"; } // 3. 接收url地址栏中参数的请求,(用户请求参数值) @RequestMapping("/add3/{a}") public String add333(@PathVariable("a")Long id) { System.out.println(id); return "/jsp/index.jsp"; } // 4. 通过传统的HttpServletRequest接收 // 4.1 将数据返回到前台页面 // 方式 1. 通过ModelAndView对象传递 @RequestMapping("/add401") public ModelAndView service(HttpServletRequest req,HttpServletResponse resp) { System.out.println(req.getParameter("username"));//获取前台页面的数据 //将数据返回到前台页面 //方式一: ModelAndView mv = new ModelAndView(); mv.addObject("msg", "登陆成功401"); mv.addObject("user",new User("TOM",401)); mv.setViewName("../jsp/index.jsp"); return mv; } //4.2 通过Model对象传递 @RequestMapping("/add402") public String add4022(Model model) { //将数据返回到前台页面 //方式二: model.addAttribute("msg", "登录成功402"); model.addAttribute("user", new User("TOM",402)); return "/jsp/index.jsp"; } //4.3 通过request对象传递 @RequestMapping("/add403") public String add4033(ServletRequest request) { //将数据返回到前台页面 //方式三: request.setAttribute("msg", "登录成功403"); request.setAttribute("user", new User("TOM",403)); return "/jsp/index.jsp"; } //4.4 通过返回值传递 @RequestMapping("/add404") public User add4044() { //将数据返回到前台页面 //方式四: User u = new User("TOM",404); return u; } }
3. 返回json数据 主要在方法上加上:@ResponseBody //返回值以json数据格式进行返回
对日期格式的特殊处理(后面要用到的知识)
从后台向前台:
默认返回的日期格式为时间戳,而在前台我们希望显示出指定规则的日期字符串。如:
默认:{"name":"小明哥","birthdate":121223223}
期望: {"name":"小明哥","birthdate":"2025-12-12 14:12:12"}
在日期get属性,字段上,添加一个格式化注解
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
从前台向后台:
在后台模型的setter方法上,添加注解
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
访问地址:localhost:8080/jsonV587?birthDay=2017-06-13 16:50:53
4. 文件下载:
@RequestMapping("/filedownload/{name}") public void download(@PathVariable("name")String filename,HttpServletRequest req,HttpServletResponse resp) throws IOException { //设置下载文件的名称(通过控制器下载文件时,浏览器可以显示你要下载的文件的文件名称) resp.setHeader("Content-Disposition","attachment;filename="+filename+".jpg"); //获取文件的输出流 OutputStream out = resp.getOutputStream(); //获取下载文件的地址 String filePath ="F:/workspace/springMVC_day01/WebContent/download/"+filename+".jpg"; //获取文件输入流 FileInputStream fis = new FileInputStream(filePath); //文件流拷贝 IOUtils.copy(fis, out); }
5.文件上传:
@RequestMapping("/fileupload") public String fileupload(String name,MultipartFile file,HttpServletRequest request) throws FileNotFoundException, IOException { System.out.println(name); System.out.println("进行文件上传"); //1.获取原始的文件名 String oldFileName = file.getOriginalFilename(); //2.获取文件的后缀名 String extName = FilenameUtils.getExtension(oldFileName); //3. 生成一个随机的文件名 String uuidname = UUID.randomUUID().toString(); String fileName = uuidname+","+extName; //4.设置文件保存的路径 String fileDir = request.getServletContext().getRealPath("/upload"); System.out.println(fileDir); File filed = new File(fileDir,fileName); if(!filed.getParentFile().exists()) { filed.getParentFile().mkdirs(); } //5. 将数据以流的方式写入该文件中 IOUtils.copy(file.getInputStream(), new FileOutputStream(filed)); return "../jsp/index.jsp"; }
5. SpringMVC的执行流程
-
用户向服务器发送请求,请求被SpringMVC前端控制DispatcherServlet捕获;
-
DispatcherServlet 接收到请求后, 将根据 请求信息 交给 处理器映射器 (HandlerMapping)
-
HandlerMapping 根据用户的url请求 查找匹配该url的 Handler,并返回一个执行链 HandlerExecutionChain对象
-
DispatcherServlet 根据获得的Handler,选择一个合适(管理Controller的方式:有xml方式和注解方式)的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)并返回 ModelAndView 给 DispatcherServlet
-
DispatcherServlet 将 ModelAndView 请求 ViewResolver(视图解析器)解析,返回具体 View
-
DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中),并将页面响应给用户。
组件说明:
-
DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,
由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
-
HandlerMapping:处理器映射器
HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,
例如:配置文件方式,实现接口方式,注解方式等。
-
Handler:处理器
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
-
HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
-
ViewResolver:视图解析器
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,
再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
视图名规则
视图名字符串前缀:
forward:/xxx.jsp 采用转发。(默认,地址栏不变)
redirect:/xxx.jsp 采用重定向。
new ModelAndView("forward:/userList");
new ModelAndView("redirect:/user");
-
View:视图
springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。