一、MVC的定义
Model:数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View:负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(调度员): 接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
最常用的MVC:(Model)Bean +(view) Jsp +(Controller) Servlet
二、servlet创建流程:
<?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>com.ssl</groupId> <artifactId>SpringMVC</artifactId> <packaging>pom</packaging> <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.2.4.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies> <!--资源过滤器,防止导入资源失败问题,最好在父子pom.xml里都加入一下代码--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
第一步:创建maven,父工程:pom.xml,如上例代码所示
第二步:创建子工程,idea右键Add Framwork Support添加web支持
第三步:实现HelloServlet继承HttpServlet接口,并创建/WEB-INF/jsp/test.jsp
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws servletexception, IOException { //1 获得参数 //2 调用业务层 //3 视图转发或者重定向 req.getRequestdispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws servletexception, IOException { super.doPost(req, resp); } }
第四步:web.xml中注册HelloServlet,测试跳转:http://localhost:8080/springmvc_01_servlet//helloServle
<?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>HelloServlet</servlet-name> <servlet-class>com.ssl.web.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/helloServlet</url-pattern> </servlet-mapping> </web-app>
三:springmvc工作原理:
SpringMVC底层工作原理:
- dispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,dispatcherServlet接收请求并拦截请求。
- 假设url为 : http://localhost:8080/SpringMVC/hello
- 服务器域名:http://localhost:8080
- web站点:/SpringMVC
- hello表示控制器:/hello
- 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
- 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,关联resource配置文件
<?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"> <!--配置dispatcherServlet:SpringMVC核心--> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherServlet</servlet-class> <!--关联一个SpringMvc的resource配置文件--> <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> <!--匹配所有的请求: / :只匹配请求,不包含所有的.jsp /*:匹配所有的请求,包括jsp页面 --> <servlet-mapping> <servlet-name>SpringMvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
第二步:配置springMvc_servlet.xml
获得视图解析器、映射器、适配器,绑定跳转url
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--处理器映射器HandlerMapping:查找访问的url控制器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!--处理器适配器HandlerAdapter:controller将处理好的数据返回给HandlerAdapter--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!--视图解析器ViewResolver:将后端处理好的数据和视图传给dispatchServlet,DS再交给ViewResolver先解析一遍,确认无误再传给前端 必须熟悉,以后还要学模版引擎Thymeleaf/Freemarker... 1 获取ModeAndView的数据 2 解析ModeAndView的视图名字 3 拼接视图名字,找到对应的视图 WEB-INF/jsp/hello.jsp --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!--BeanNameUrlHandlerMapping处理器:绑定跳转的url=页面访问的网址--> <bean id="/hello" class="com.ssl.controller.HelloController"/> </beans>
第三步:/WEB-INF/jsp/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>hello</title> </head> <body> <%--接受传递的参数--%> ${msg} </body> </html>
第四步:HelloController实现Controller
访问:http://localhost:8080/springmvc_02_hellomvc/hello
public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { //1 创建modelAndView ModelAndView mv = new ModelAndView(); //2 调用业务层,这里没有,就不写 //3 封装对象,放在mv中添加 mv.addobject("msg", "Hello SpringMvc"); //4 封装要跳转的视图,WEB-INF/jsp/hello.jsp mv.setViewName("hello"); return mv; } }
如使用注解开发:
第一步:配置web.xml
<?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_servlet.xml
注解省略了映射器、适配器,专注于写视图解析器;跳转的Controller也不用配置进Spring
<?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 https://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"> <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理--> <context:component-scan base-package="com.ssl.controller"/> <!--让SpringMvc不处理静态资源。让.css,.js等不进视图解析器--> <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>
第三步:/WEB-INF/jsp/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>hello</title> </head> <body> ${msg} </body> </html>
第四步:HelloController
简化了实现的接口,使用@注解配置映射器
访问:http://localhost:8080/springmvc_03_annotation/hello
@Controller public class HelloController { /** * @param model 模型 * @return 被视图解析器处理:访问"/WEB-INF/jsp/hello.jsp资源 * 访问的url:RequestMapping("/hello") */ @RequestMapping("/hello") public String hello(Model model) { //封装数据 model.addAttribute("msg", "Hello SpringMvc_annotation"); //被视图解析器处理:访问"/WEB-INF/jsp/hello.jsp资源 return "hello"; }