目录
什么是MVC
SpringMVC概述
SpringMVC常见开发方式
SpringMVC执行流程
SpringMVC核心组件介绍
快速构建Spring MVC程序
SpringMVC参数绑定
SpringMVC跳转方式
SpringMVC处理json请求和响应
SpringMVC静态资源处理
SpringMVC拦截器
SpringMVC文件的上传
SpringMVC全局异常统一处理
SSM框架整合
1.引入pom依赖
2.设置配置文件
3.项目目录结构
MVC 设计模式一般指 MVC 框架,M(Model)指数据模型层,业务模型层,V(View)指视图层,C(Controller)指控制层。使用 MVC 的目的是将 M 和 V 的实现代码分离,使同一个程序可以有不同的表现形式。
MVC 属于架构模式的一种,所谓架构就是如何设计一个程序的结构。MVC 将程序结构划分为三层,每一层都对外提供了可供上层调用的接口,既能维系三层之间的联系,也能保持相对的独立性。
这种将业务逻辑、数据和界面分离的代码组织形式,降低了模块间的耦合度,有利于日后的维护与扩展。
springmvc是基于spring Framwork衍生出来的一个mvc框架,主要解决原有mvc架构中,控制器(Controller)的问题,常见的控制器有servlet,struts2等,控制器的核心功能是根据用户的请求调用对应业务功能,然后依据业务处理的结果,控制程序的运行流程。
servlet实现控制器存在的问题:
1.接收客户端请求参数时,存在代码的冗余
2.只能接收字符串类型的数据,其它数据类型需要手动的转换
3.无法接收对象类型的参数
4.调用业务对象存在耦合 (new)
5.流程跳转存在耦合(路径耦合,视图耦合)
1.传统的开发方式
通过作用域(request,session)实现数据的传递
通过视图技术进行视图的渲染(jsp thymleaf freeMarker)
2.前后端分离开发方式
多种新的访问方式(get 、post 、put、 delete)
Restful风格的访问
Spring MVC 框架是高度可配置的,包含多种视图技术,例如 JSP、FreeMarke和 POI。Spring MVC 框架并不关心使用的视图技术,也不会强迫开发者只使用 JSP。
Spring MVC 执行流程如图 所示:
SpringMVC 的执行流程如下:
用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器);
由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)。
DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
视图负责将结果显示到浏览器(客户端)
Spring MVC 涉及到的组件有 DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器)、ViewResolver(视图解析器)和 View(视图)。下面对各个组件的功能说明如下。
1)DispatcherServlet
DispatcherServlet 是前端控制器,从图 1 可以看出,Spring MVC 的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
2)HandlerMapping
HandlerMapping 是处理器映射器,其作用是根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息。
3)HandlerAdapter
HandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)。
4)Handler
Handler 是处理器,和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。
5)View Resolver
View Resolver 是视图解析器,其作用是进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如通过一个 JSP 路径返回一个真正的 JSP 页面)
6)View
View 是视图,其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等)。
以上组件中,需要开发人员进行开发的是处理器(Handler,常称Controller)和视图(View)。通俗的说,要开发处理该请求的具体代码逻辑,以及最终展示给用户的界面
搭建步骤如下:
创建 Web 应用并引入 JAR 包
spring-webmvc
Spring MVC 配置:在 web.xml 中配置 Servlet,创建 Spring MVC 的配置文件
springmvc配置文件
创建 Controller(处理请求的控制器)
创建 View(使用 JSP 作为视图)
部署运行
@RequestMapping详解
1.一个方法匹配多个路径
2.指定方法接收的请求方式
视图传参到控制器
1.基本数据类型绑定
形参的名字和传递参数的名字保持一致,参数需要全部传递否则报500错误,为了解决不传参报错,可以给基本类型的参数设置默认值
设置参数的别名
2.包装数据类型的传递
使用包装类型可以解决基本类型不传递值,出现500错误的问题但是还是要保持参数名字和形参保持一致,
3.字符串类型数据的绑定
参照包装类即可
4.数组类型
5.javaBean类型
参数名的字段和Javabean中的属性保持一致即可
返回数据到视图层
Spring MVC默认采用服务器内部转发的形式展示页面信息,同时也支持重定向页面
重定向(302状态码给浏览器)
响应json格式的数据
请求数据类型为JSON
/*** 接收json格式的参数* @param user* @return*/@RequestMapping("/login4")@ResponseBodypublic Object login4(@RequestBody User user) {System.out.println(user);return user;}
}前台ajax请求
RestFul风格
一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制
URL定义
资源:互联网所有的事物都可以被抽象为资源 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。 分别对应 添加、 删除、修改、查询
传统方式操作资源
http://127.0.0.1/item/queryUser.action?id=1 查询,GET http://127.0.0.1/item/saveUser.action 新增,POST http://127.0.0.1/item/updateUser.action 更新,POST http://127.0.0.1/item/deleteUser.action?id=1 删除,GET或POST
RestFul请求方式 可以通过 GET、 POST、 PUT、 PATCH、 DELETE 等方式对服务端的资源进行操作。其中:
1.实现Handlerlnterceptor接口
GET 用于查询资源,
POST 用于创建资源,
PUT 用于更新服务端的资源的全部信息,
DELETE 用于删除服务端的资源。
public class RestController {@GetMapping("/rest")public void test01(){System.out.println("test01: ");} @PostMapping("/rest")public void test02(){System.out.println("test02: ");}@DeleteMapping("/rest")public void test03(){System.out.println("test03:");}@PutMapping("/rest")public void test04(){System.out.println("test04: ");}@PatchMapping("/rest")public void test05(){System.out.println("test05: ");}}
表单发送PUT请求设置方式
设置web.xml
REST风格传参问题
数据提交中文乱码的处理
1.配置静态资源的路径
2.配置使用tomcat的servlet处理器
@Controller
@SessionAttributes({"model1","model2"})
public class SessionController {@RequestMapping("/s1")public void test01(HttpSession session){session.setAttribute("msg", "session attribute");}@RequestMapping("/s2")public void test02(HttpSession session){System.out.println(session.getAttribute("msg"));}/*** 将model放入session作用域* @param model*/@RequestMapping("/s3")public void test03(Model model){model.addAttribute("model1", "model1 attribute");}/*** 获取通过注解设置的session域中的值* @param session*/@RequestMapping("/s5")public void test05(HttpSession session){System.out.println("msg: "+session.getAttribute("msg"));System.out.println("model1 :"+session.getAttribute("model1"));System.out.println("model2 :"+session.getAttribute("model2"));}/*** 通过注解获取session域中的值* @param*/@RequestMapping("/s6")public void test05(@SessionAttribute(name = "msg") String session){System.out.println(session);}
操作cookie
public class CookieController {@RequestMapping("/c1")public void test01(HttpServletResponse response){Cookie ck = new Cookie("cookie","cookieValue");ck.setPath("/");ck.setMaxAge(60*60*24*7);response.addCookie(ck);}/*** 获取cookie中值的方式1* @param request*/@RequestMapping("/c2")public void test02(HttpServletRequest request){Cookie[] cookies = request.getCookies();for (int i = 0; i < cookies.length; i++) {System.out.println(cookies[i].getName()+":"+cookies[i].getValue());}}/*** 获取cookie中值的方式2 注解方式* @param cookie*/@RequestMapping("/c3")public void test03(@CookieValue("cookie") String cookie){System.out.println(cookie);}
}
SpringMVC中的Interceptor拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的 处理。比如通过它来进行权限验证,或者是来判断用户是否登录等操作。对于SpringMVC拦截器的定义方式有两 种
实现接口: org.springframework.web.servlet.Handlerlnterceptor
继承适配器: org.springframework.web.servethandler.HandlerInterceptorAdapter
1.实现Handlerlnterceptor接口
2.继承HandlerInterceptorAdapter(不建议使用)
使用拦截器拦截非法请求
/***用户操作模拟实现* 用户的登录(无需登录)* 用户的添加(登录)* 用户修改(登录)* 用户删除(登录)** @author mosin* date 2021/8/22* @version 1.0*/
@Controller
@RequestMapping("/user")
@SessionAttributes("action")
public class UserInfoController {/*** 用户登录*/@RequestMapping("/login")public ModelAndView login(HttpSession session){ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("success");User user = User.builder().password("123456").username("lisi").build();session.setAttribute("user", user);modelAndView.addObject("user", user);return modelAndView;}/*** 用户添加*/@RequestMapping("/add")public String add(Model model){model.addAttribute("action", "用户添加成功");System.out.println("用户的添加方法");return "success";}/*** 用户修改*/@RequestMapping("/update")public String update(Model model){System.out.println("用户的更新方法");model.addAttribute("action", "用户更新成功");return "success";}/*** 用户修改*/@RequestMapping("/delete")public String delete(Model model){System.out.println("用户的删除方法");model.addAttribute("action", "用户删除成功");return "success";}}
添加坐标依赖
配置解析器
后台代码
@Controller
@RequestMapping("/upload")
public class UPloadController {@RequestMapping("/file")public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request){//获取项目的真实路径String realPath = request.getSession().getServletContext().getRealPath("/");System.out.println(realPath);//创建文件上传的目录File dir = new File(realPath, "/upload");System.out.println(dir);//判定文件夹是否存在 不存在创建if(!dir.exists()){dir.mkdir();}if(!file.isEmpty()){//获取文件的名字String fileName = file.getOriginalFilename();//截取文件的后缀 生成新的文件名 避免文件名字重复String suffix= fileName.substring(fileName.lastIndexOf("."));//获取当前系统时间String fileLastName = System.currentTimeMillis()+suffix;System.out.println(fileLastName);//将文件写入目标文件夹try {file.transferTo(new File(dir,fileLastName));request.setAttribute("msg", "文件上传成功");} catch (IOException e) {e.printStackTrace();request.setAttribute("msg", "文件上传失败");}}else{request.setAttribute("msg", "未选择文件");}return "success";}@RequestMapping("/files")public String uploads(@RequestParam("files") List files, HttpServletRequest request){//遍历集合files.forEach(multipartFile -> {FileUploadUtil.upload(multipartFile, request);});return "success";}
}
1.处理的方式1 使用 @ExceptionHandler(Exception.class) 在类中定义一个异常的方法,处理本类中的指定异常
@RestController
@RequestMapping("/exception")
public class ExceptionController01 {@ExceptionHandler(Exception.class)public Object handlerException(Exception e){return JsonResult.builder().msg("出现"+"异常").code(1).data(e.getMessage()).build();}@RequestMapping("/e1")public Object ex1(){int a = 1/0;return null;}@RequestMapping("/e2")public Object ex2() throws FileNotFoundException {new FileInputStream("ab");return null;}
}
2.处理的方式2 全局处理模式 定义ExceptionAdvice类
1.引入mybatis依赖
org.mybatis mybatis 3.5.7
com.github.pagehelper pagehelper 5.2.1
org.mybatis mybatis-spring 2.0.5
2.引入spring依赖
org.springframework spring-context 5.3.9
org.springframework spring-aspects 5.3.9
org.springframework spring-jdbc 5.3.9
3.springmvc依赖
org.springframework spring-webmvc 5.3.9
com.fasterxml.jackson.core jackson-core 2.11.3
com.fasterxml.jackson.core jackson-databind 2.11.3
com.fasterxml.jackson.core jackson-annotations 2.11.3 commons-fileupload commons-fileupload 1.4
4.log4j依赖
log4j log4j 1.2.17 org.apache.logging.log4j log4j-api 2.13.3 org.apache.logging.log4j log4j-core 2.13.1
5.数据库驱动和连接池
mysql mysql-connector-java 5.1.44 com.alibaba druid 1.1.10
6.servlet+jsp依赖
javax.servlet javax.servlet-api 4.0.1
javax.servlet.jsp jsp-api 2.2
7.jstl依赖
javax.servlet jstl 1.2 taglibs standard 1.1.2
8.其它依赖
org.projectlombok lombok 1.18.16
junit junit 4.11 test
3.spring核心配置文件
4.spring-mvc配置文件
104857600 4096 utf-8
5.mybatis配置文件
6.web.xml
ssm org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:config/spring-*.xml 1 ssm *.do encoding org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 encoding /
下一篇:λ演算参考文章