1. 什么是 SpringMvc?
Spring MVC 是一个基于 MVC(Model view Controller)模式的 web 框架, 它解决 Web 开发中常见的问题 (参数接收, 文件上传, 表单验证, 国际化, 等等), 使用非常简单, SpringMvc 作为 Spring 中的一个模块, 可以与 Spring 无缝集成, 为应用程序中的 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>
- View Code
这里是 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>
- View Code
注意:
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>
- View Code
2. 如果我们把 spring 的配置文件放在 Web-INF 文件夹中, 不需要在 Web.xml 中配置上面代码. 但是:
启动 Tomcat 服务器的时候会初始化 SpringMVC 中的 DispatcherServlet, 而这个 DispatcherServlet 会根据配置文件初始化 Spring 容器, 默认配置文件路径为:/Web-INF/<servlet-name>-servlet.xml.
故: 把配置文件更名为 springmvc-servlet.xml.
3. springmvc 控制器三种实现方式
1 实现 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;
- }
- }
2 实现 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");
- }
- }
3 普通类 (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. 参数接收方式
1 通过控制器的执行方法参数来接收普通参数
2 通过 Domain 模型对象来接收
3 通过传统的 HttpServletRequest 接收
4 通过 url 中的参数接收 (restfull 风格) @PathVariable("id") 转换
2. 数据传递
就是 Controller 往前台 (页面) 传递数据
1 通过 ModelAndView 对象传递
2 通过 Model 对象传递
3 通过 request 对象传递
4 通过返回值传递
具体代码如下:
- @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 的执行流程 https://www.cnblogs.com/gxc6/p/9544563.html
一个请求匹配前端控制器 DispatcherServlet 的请求映射路径(在 Web.xml 中指定), Web 容器将该请求转交给 DispatcherServlet 处理
DispatcherServlet 接收到请求后, 将根据 请求信息 交给 处理器映射器 (HandlerMapping)
HandlerMapping 根据用户的 url 请求 查找匹配该 url 的 Handler, 并返回一个执行链
DispatcherServlet 再请求 处理器适配器(HandlerAdapter) 调用相应的 Handler 进行处理并返回 ModelAndView 给 DispatcherServlet
DispatcherServlet 将 ModelAndView 请求 ViewReslover(视图解析器)解析, 返回具体 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 进行渲染将处理结果通过页面展示给用户.
View: 视图
springmvc 框架提供了很多的 View 视图类型的支持, 包括: jstlView,freemarkerView,pdfView 等. 我们最常用的视图就是 jsp.
参考: https://www.cnblogs.com/gxc6/p/9544563.html
来源: http://www.bubuko.com/infodetail-2985599.html