SpringMVC
一、MVC 概述 1.1.什么是 MVC
MVC是模型(Model
)、视图(View)、 控制器(Controller)的简写, 是一种软件设计规范。
是将业务逻辑、数据、显示分离的方法来组织代码。
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
MVC不是一种设计模式,MVC是-种架构模式。当然不同的MVC存在差异。
Model
(模型) :数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean
组件(包含数据和行为),不过现在-般都分离开来: Value Object
(数据Dao
)和服务层(行为Service
) 。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View
(视图) :负责进行模型的展示,-般就是我们见到的用户界面,客户想看到的东西。
Controller
(控制器) :接收用户请求,委托给模型进行处理(状态改变), 处理完毕后把返回的 模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
Model 1 时代
Model 2 时代
1.2.导入依赖 pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?xml version="1.0" encoding="UTF-8"?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > org.cying.study</groupId > <artifactId > SpringMVC</artifactId > <version > 1.0-SNAPSHOT</version > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > </dependency > </dependencies > </project >
1.3.特点
轻量级,简单易学
高效,基于请求响应的 MVC
框架
与 Spring
兼容性好,无缝结合
约定优于配置
功能强大: RESTful
、数据验证、格式化、本地化、主题等
简洁灵活
1.4.中心控制器
Spring
的 web
框架围绕 DispatcherServlet
设计。DispatcherServlet
的作用是将请求分发到不同的处理器。从 Spring 2.5
开始,使用 Java 5
或者以上版本的用户可以采用基于注解的 controller
声明方式。
1.5.原理
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
1.6.执行流程分析
DispatcherServlet
表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet
接收请求并拦截请求。
HandlerMapping
为处理器映射。DispatcherServlet
调用HandlerMapping
,HandlerMapping
根据请求url
查找Handler
。
HandlerExecution
表示具体的Handler
,其主要作用是根据url
查找控制器,如上url
被查找控制器为: hello
。
HandlerExecution
将解析后的信息传递给DispatcherServlet
,如解析控制器映射等。
HandlerAdapter
表示处理器适配器,其按照特定的规则去执行Handler
。
Handler
让具体的Controller
执行。
Controller
将具体的执行信息返回给HandlerAdapter
,如ModelAndView
。
HandlerAdapter
将视图逻辑名或模型传递给DispatcherServlet
。
DispatcherServlet
调用视图解析器(ViewResolver
)来解析HandlerAdapter
传递的逻辑视图名。
视图解析器将解析的逻辑视图名传给DispatcherServlet
。
DispatcherServlet
根据视图解析器解析的视图结果,调用具体的视图。
最终视图呈现给用户。
二、具体实现 在 web.xml 注册 DispatcherServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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 > springmvc</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:springmvc-servlet.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 > </web-app >
在 resources 新建 springmvc-servlet.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?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: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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd" > <context:component-scan base-package ="包路径" /> <bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <bean class ="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean > </beans >
2.1.原始方法实现 在 springmvc-serlvet.xml 配置
Spring Bean`,指向实体类
1 <bean class ="实体类全路径" id ="/外界访问路径" />
书写实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 FirstTest implements Controller { public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); System.out.println("Do" ); mv.addObject("msg" ,"HelloSpringMVC!" ); mv.setViewName("hello" ); return mv; } }
2.2.注解方式实现 **修改 `springmvc-servlet.xml **
1 2 3 4 5 6 7 8 9 10 <bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <bean class ="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> 改为: <mvc:default-servlet-handler /> <mvc:annotation-driven />
书写实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("/HelloController") public class HelloController { @RequestMapping("/hello") public String sayHello (Model model) { model.addAttribute("msg" ,"hello,SpringMVC" ); return "hello" ; } }
三、数据处理 3.1.处理提交数据 3.1.1.提交时的 url 和参数名一样时 1 http://localhost/url?name=xx&age=xx
1 2 3 4 5 @RequestMapping("/url") public String hello (String name, int age) { System.out.println(name + age); return "hello" ; }
3.1.2.提交时的 url 和参数名不一样时 1 http://localhost/url?name=xx
1 2 3 4 5 @RequestMapping("/url") public String hello (@RequestParam("name") String Username) { System.out.println(Username); return "hello" ; }
3.1.3.提交一个对象 1 2 3 4 5 6 7 8 9 10 @Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; }
1 http://localhost/url?name=xx&age=xx
1 2 3 4 5 @RequestMapping("/url") public String user (User user) { System.out.println(user); return "hello" ; }
3.2.数据显示到前端 3.2.1.ModelAndView 1 2 3 4 5 6 7 8 9 10 public class Controller implements Controller { public ModelAndView handleRequest (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" ,"value" ); mv.setViewName("test" ); return mv; } }
3.2.2.ModelMap 1 2 3 4 5 6 7 8 @RequestMapping("/url") public String hello (@RequestParam("username") String name, ModelMap model) { model.addAttribute("name" ,name); System.out.println(name); return "hello" ; }
3.2.3.Model 1 2 3 4 5 6 7 8 @RequestMapping("/url") public String hello (@RequestParam("username") String name, Model model) { model.addAttribute("msg" ,name); System.out.println(name); return "test" ; }
3.2.4.对比
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
3.2.5.过滤器解决乱码 在 web.xml
配置
1 2 3 4 5 6 7 8 9 10 11 12 <filter > <filter-name > encoding</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 > encoding</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
四、RestFul 4.1.概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
4.2.功能
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。
4.3.映射访问路径 1 2 3 4 5 6 7 8 9 10 @RequestMapping("/commit/{p1}/{p2}") public String index (@PathVariable int p1, @PathVariable String p2, Model model) { String result = p1+p2; model.addAttribute("msg" , "结果:" +result); return "test" ; }
4.4.RequestMapping 1 2 3 4 5 6 7 8 @RequestMapping(value = "/url",method = {RequestMethod.POST}) @PostMapping @RequestMapping(value = "/url",method = {RequestMethod.GET}) @GetMapping
五、拦截器 书写拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor { public boolean preHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("------------处理前------------" ); return true ; } public void postHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("------------处理后------------" ); } public void afterCompletion (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("------------清理------------" ); } }
在 springmvc-servlet.xml
中配置
1 2 3 4 5 6 7 8 9 10 <mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/**" /> <bean class ="拦截器全路径" /> </mvc:interceptor > </mvc:interceptors >
六、文件 6.1.上传 在 pom.xml
导入依赖
1 2 3 4 5 6 7 8 9 10 11 <dependency > <groupId > commons-fileupload</groupId > <artifactId > commons-fileupload</artifactId > <version > 1.3.3</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 4.0.1</version > </dependency >
在 springmvc-servlet.xml
中配置 Java Bean
1 2 3 4 5 6 7 8 <bean id ="multipartResolver" class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name ="defaultEncoding" value ="utf-8" /> <property name ="maxUploadSize" value ="10485760" /> <property name ="maxInMemorySize" value ="40960" /> </bean >
书写实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.multipart.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;import java.io.*;@Controller public class FileController { @RequestMapping("/upload") public String fileUpload (@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException { String uploadFileName = file.getOriginalFilename(); if ("" .equals(uploadFileName)){ return "redirect:/index.jsp" ; } System.out.println("上传文件名 : " +uploadFileName); String path = request.getServletContext().getRealPath("/upload" ); File realPath = new File(path); if (!realPath.exists()){ realPath.mkdir(); } System.out.println("上传文件保存地址:" +realPath); InputStream is = file.getInputStream(); OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); int len=0 ; byte [] buffer = new byte [1024 ]; while ((len=is.read(buffer))!=-1 ){ os.write(buffer,0 ,len); os.flush(); } os.close(); is.close(); return "redirect:/index.jsp" ; } }
6.2.下载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @RequestMapping(value="/download") public String downloads (HttpServletResponse response ,HttpServletRequest request) throws Exception { String path = request.getServletContext().getRealPath("/upload" ); String fileName = "基础语法.jpg" ; response.reset(); response.setCharacterEncoding("UTF-8" ); response.setContentType("multipart/form-data" ); response.setHeader("Content-Disposition" , "attachment;fileName=" +URLEncoder.encode(fileName, "UTF-8" )); File file = new File(path,fileName); InputStream input=new FileInputStream(file); OutputStream out = response.getOutputStream(); byte [] buff =new byte [1024 ]; int index=0 ; while ((index= input.read(buff))!= -1 ){ out.write(buff, 0 , index); out.flush(); } out.close(); input.close(); return null ; }
Ajax
url:请求地址
type:请求方式,
GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: “application/x-www-form-urlencoded; charset=UTF-8”)
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
“xml”: 将服务器端返回的内容转换成xml格式
“text”: 将服务器端返回的内容转换成普通文本格式
“html”: 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
“script”: 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
“json”: 将服务器端返回的内容转换成相应的JavaScript对象
“jsonp”: JSONP 格式使用 JSONP 形式调用函数时,如 “myurl?callback=?” jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
在类上直接使用 @RestController ,这样子,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !我们在前后端分离开发中,一般都使用 @RestController ,十分便捷!