MVC 概念
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
是将业务逻辑、数据、显示分离的方法来组织代码。
MVC主要作用是降低了视图与业务逻辑间的双向偶合 。
MVC不是一种设计模式,MVC是一种软件架构模式 。
**Model(模型):**数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
**View(视图):**界面设计人员进行图形界面设计。
**Controller(控制器):**负责转发请求,对请求进行处理。
MVC 程序(配置版)
目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |-- pom.xml |-- src | |-- main | | |-- java | | | `-- com | | | `-- kanxz | | | `-- controller | | | `-- HelloController.java | | `-- resources | | `-- springmvc-servlet.xml | `-- test | `-- java `-- web |-- WEB-INF | |-- jsp | | `-- hello.jsp | `-- web.xml `-- index.jsp
maven添加依赖:
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 <dependencies > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.2.12.RELEASE</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > javax.servlet.jsp-api</artifactId > <version > 2.3.3</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet.jsp.jstl</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > org.junit.jupiter</groupId > <artifactId > junit-jupiter-api</artifactId > <version > 5.4.2</version > <scope > test</scope > </dependency > </dependencies >
首先配置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 25 26 <?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 >
编写SpringMVC 的 配置文件: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 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" 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" > <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 >
编写我们要操作业务Controller ,要么实现Controller接口,要么增加注解;需要返回一个ModelAndView,装数据,封视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class HelloController implements Controller { @Override public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" , "Hello SpringMVC!" ); mv.setViewName("hello" ); return mv; } }
将自己的类交给SpringIOC容器,注册bean
1 2 <bean id ="/hello" class ="com.kanxz.controller.HelloController" />
写要跳转的jsp页面,显示ModelandView存放的数据,以及我们的正常页面
1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Hello</title> </head> <body> ${msg} </body> </html>
配置Tomcat 启动测试
(404解决:https://www.codenong.com/cs111051809/)
MVC 原理
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。
Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能 ,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类) 。
SpringMVC的原理如下图所示:
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
SpringMVC的工作原理
1、 用户发送请求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。
MVC 程序(注解版)
配置web.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 <?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 >
在resource目录下添加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 27 28 29 30 31 32 33 34 35 36 37 38 <?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 ="com.kanxz.helloannotaition" /> <mvc:default-servlet-handler /> <mvc:annotation-driven /> <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="internalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean > </beans >
编写一个Java控制类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.kanxz.controller;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" ; } }
@Controller
是为了让Spring IOC容器初始化时自动扫描到;
@RequestMapping
是为了映射请求路径,这里因为类与方法上都有映射所以访问时应该是/HelloController/hello;
方法中声明Model类型的参数是为了把Action中的数据带到视图中;
方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello .jsp。
在WEB-INF/ jsp目录中创建hello.jsp , 视图可以直接取出并展示从Controller带回的信息
1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
配置Tomcat 启动测试
RestFul 风格
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
代码演示:
代码框架同上
首先不使用RestFul风格:
1 2 3 4 5 6 7 8 9 10 @Controller public class RestFulController { @RequestMapping("/add") public String add (int a, int b, Model model) { int res = a + b; model.addAttribute("msg" , "结果:" + res); return "test" ; } }
运行上述代码,需要在地址栏输入:http://localhost:8080/SpringMVC/add?a=1&b=2
,得到:结果:3
然后使用RestFul风格:
1 2 3 4 5 6 7 8 9 @Controller public class RestFulController { @RequestMapping("/add/{a}/{b}") public String add (@PathVariable int a, @PathVariable int b, Model model) { int res = a + b; model.addAttribute("msg" , "结果:" + res); return "test" ; } }
那么在地址栏输入:http://localhost:8080/SpringMVC/add/1/2
,得到:结果:3
使用method
属性可以指定请求类型:
1 @RequestMapping(value = "/add/{a}/{b}", method = RequestMethod.GET)
指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
也可以简写为:
1 @GetMapping("/add/{a}/{b}")
相应也有:
1 2 3 4 5 @PostMapping @PutMapping @DeleteMapping @PatchMapping ...
处理提交数据
定义参数
1 2 3 4 5 @GetMapping("/user") public String getData (@RequestParam("name") String name) { System.out.println(name); return "test" ; }
当地址栏输入为http://localhost:8080/SpringMVC/user?name=zhangsan
时,会输出zhangsan
单个参数的时候可以省略@RequestParam
获取多个参数
1 2 3 4 5 6 @GetMapping("/user") public String getData (@RequestParam("name") String name, @RequestParam("age") int age) { System.out.println(name); System.out.println(age); return "test" ; }
非必须传递参数
1 2 3 4 5 @GetMapping("/user") public String getData (@RequestParam("name") String name, @RequestParam(value = "age", required = false) int age) { System.out.println(name); return "test" ; }
对象参数
1 2 3 4 5 @GetMapping("/user") public String getData (User user) { System.out.println(user); return "test" ; }
地址栏输入User
的属性值:http://localhost:8080/SpringMVC/user?name=lisi&age=11&id=1
表单乱码问题处理
首先定义form.jsp
:
1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Form</title> </head> <body> <form action="encode" method="post" > <input type="text" name="name" > <input type="submit" > </form> </body> </html>
在定义控制类:
1 2 3 4 5 6 7 8 9 @Controller public class EncodingController { @PostMapping("/encode") public String encodeTest (String name, Model model) { model.addAttribute("msg" , name); return "test" ; } }
输入中文得到乱码
而SpringMVC给我们提供了一个过滤器 , 可以在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 >
Json交互处理
JSON 和 JavaScript 对象互转
要实现从JSON字符串转换为JavaScript 对象,使用JSON.parse()
方法:
1 2 var obj = JSON .parse('{"a": "Hello", "b": "World"}' );
要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify()
方法:
1 2 var json = JSON .stringify({a : 'Hello' , b : 'World' });
Controller返回JSON数据
使用Jackson
:
1 2 3 4 5 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.12.0</version > </dependency >
定义User
实体类
定义Controller
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Controller public class UserController { @RequestMapping("/j1") @ResponseBody public String UserJson () throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); User user = new User("张三" , "男" , 18 ); return mapper.writeValueAsString(user); } }
使用@ResponseBody
会将str转成json字符串输出到网页上
也可以在类上加@RestController
,这样子,里面所有的方法都只会返回 json 字符串
这样启动Tomcat 会得到乱码
Json乱码处理
可以通过@RequestMaping
的produces
属性来实现,修改下代码
1 2 @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
再次测试:http://localhost:8080/SpringMVC/j1
,得到:{"name":"张三","sex":"男","age":18}
在springmvc的配置文件上:springmvc-servlet.xml
添加一段消息StringHttpMessageConverter
转换配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <mvc:annotation-driven > <mvc:message-converters register-defaults ="true" > <bean class ="org.springframework.http.converter.StringHttpMessageConverter" > <constructor-arg value ="UTF-8" /> </bean > <bean class ="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" > <property name ="objectMapper" > <bean class ="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" > <property name ="failOnEmptyBeans" value ="false" /> </bean > </property > </bean > </mvc:message-converters > </mvc:annotation-driven >
学习自: