赞
踩
目录
(1)首先我们先回忆一下MVC的三层架构?
MVC是一种开发模式,它是模型、视图、控制器的简称;所有的web应用都是基于MVC开发
M:Model,模型层,指工程中的JavaBean,作用是处理数据;JavaBean分为两类:①一类称为实体类Bean:专门存储业务数据的,如 Student、User 等。
②一类称为业务处理 Bean:指 Service【业务逻辑层】 或 Dao【数据访问层】 对象,专门用于处理业务逻辑和数据访问。
总结:包含实体类、业务逻辑层、数据访问层。
V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据
C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器MVC的工作流程:用户通过视图层【jsp或html】发送请求到服务器,在服务器中请求被Controller接收【servlet】,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller【JavaBean】,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器。
(2)什么是SpringMVC?
①SpringMVC是Spring的一个后续产品,是Spring的一个子项目;它是基于MVC开发模式的框架,用来优化控制器,它是Spring家族的一员;也具备IOC和AOP。
②SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案。
注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表示层表示前台页面(jsp或jsp)和后台servlet。所有MVC与三层架构的关系是:
①三层架构的业务逻辑层、数据访问层实际上就是MVC架构模式的M。
②而MVC架构模式的V(jsp或servlet)和 C(servlet)实际上就是三层架构的表示层。
(3)SSM框架的优化方向?
①MyBatis是用来优化数据访问层(持久层框架)。
②SpringMVC是用来优化控制机器,例如:Servlet。
③Spring是用来整合其它框架的。
(1)特点
①Spring 家族原生产品,与 IOC 容器等基础设施无缝对接。
②基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理。
③表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案。
④代码清新简洁,大幅度提升开发效率。
⑤内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可。
⑥性能卓著,尤其适合现代大型、超大型互联网项目要求。
(2)优点
①基于MVC架构。基于 MVC 架构,功能分工明确;解耦合。
②容易理解,上手快,使用简单。可以开发一个注解的 SpringMVC 项目,SpringMVC 也是轻量级的,jar 很小;不依赖的特定的接口和类。
③具备IOC和AOP。方便整合Strtus、MyBatis、Hiberate等其他框架。
④强化注解的使用(全注解开发)。在Controller, Service, Dao 都可以使用注解,方便灵活。使用@Controller创建处理器对象、@Service创建业务对象,@Autowired 或者@Resource 在控制器类中注入 Service,在Service 类中注入 Dao。
(1)用户发出请求首先是要交给Tomcat服务器,然后检查web.xml配置;如果在里面配置了SpringMVC(DispatcherServlet)就把控制权交给这个框架。
(2)SpringMVC调用控制器Controller,会对客户端提交的数据进行优化、携带数据进行优化、返回跳转进行优化。
(3)然后控制器调用业务逻辑层,业务逻辑层调用数据访问层;然后数据访问层连接数据库,最终返回数据。
(1)客户端向服务器发送HTTP请求,请求被前置控制器DispatcherServlet(SpringMVC框架的核心处理器) 捕获。
(2)DispatcherServlet(前置控制器)【好汉】根据<servlet-name>中的配置(DispatcherServlet)对请求的URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用 HandlerMapping(地址映射器)【第一个小帮手】 获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。
(3)DispatcherServlet 根据获得的Handler,选择一个合适的 HandlerAdapter(适配器)【第二个小帮手】,然后去调用业务逻辑层、数据访问层,最终一个ModelAndView对象。
(4)解析:提取Request中的模型数据,填充Handler入参,开始执行Handler。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
①数据转换:对请求消息进行数据转换;如String转换成Integer、Double等
②数据格式化:对请求消息进行数据格式化;如将字符串转换成格式化数字或格式化日期等
③数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
Handler执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象。
(5)根据返回的ModelAndView,选择一个适合的 ViewResolver(视图解析器,必须是已经注册到Spring容器中的ViewResolver)【第三个小帮手】,主要是用来返回客户端请求地址拼接,分为前缀部分和后缀部分,最终返回给DispatcherServlet。
(6)ViewResolver 结合Model和View,来渲染视图;视图负责将渲染结果返回给客户端。
第一步:新建项目,选择webapp模板
第二步:修改目录,添加缺失的test,java、resources(两套),并修改目录属性
第三步:修改pom.xml文件,添加SpringMVC的依赖,添加Servlet的依赖
对于最后指定资源文件的解析:maven默认会把src/main/resources下的所有配置文件以及src/main/java下的所有java文件打包或发布到target\classes下面;我们可能会在src/main/java下面也放置一些配置文件如:xxx.xml配置、xxx.properties配置;如果不做一些额外配置,那我们打包后的项目可能找不到这些必须的资源文件!
注:对于Tomcat9+spring-webmvc依赖(使用5.3版本以下才好使)+javax.servlet.api
注:对于高版本的Tomcat实际上内置了Servlet,所以当我们设置了scope为provided,实际上在打包的时候就不会出现在WEB-INF目录下!
- <?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.bjpowernode</groupId>
- <artifactId>SpringMVC-001</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>war</packaging>
-
- <name>SpringMVC-001 Maven Webapp</name>
- <!-- FIXME change it to the project's website -->
- <url>http://www.example.com</url>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
- </properties>
-
- <dependencies>
- <!--添加SpringMVC依赖-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.2.5.RELEASE</version>
- </dependency>
- <!--添加Servlet依赖-->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.11</version>
- <scope>test</scope>
- </dependency>
- <!-- Spring和Thymeleaf整合包 -->
- <dependency>
- <groupId>org.thymeleaf</groupId>
- <artifactId>thymeleaf-spring5</artifactId>
- <version>3.0.10.RELEASE</version>
- </dependency>
- </dependencies>
-
- <build>
- <!--指定资源文件-->
- <resources>
- <resource>
- <directory>src/main/java</directory>
- <includes>
- <include>**/*.xml</include>
- <include>**/*.properties</include>
- </includes>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- <includes>
- <include>**/*.xml</include>
- <include>**/*.properties</include>
- </includes>
- </resource>
- </resources>
- </build>
- </project>
第四步:删除web.xml文件(版本低),新建web.xml;并在在web.xml文件中注册springMVC框架
注:我们知道所有的web请求都是基于servlet的,但是SpringMVC的处理器本身却是一个普通的方法;所以需要核心处理器DispatcherServlet,DispatcherServlet要在web.xml文件中注册才可以使用!
①添加初始化配置:指定DispactherServlet要拦截什么样的请求?
②引入springmvc.xml配置:使用contextConfigLocation作为name,classpath:springmvc.xml作为value来引入springmvc.xml配置,告诉DispatchServlet处理
注:设置springMVC的核心控制器所能处理的请求的请求路径,【斜杠/】所匹配的请求可是/login或.html或.js或.css方式的请求路径;但是/不能匹配.jsp请求路径的请求!
注:斜杠【/】表示所有请求,但不包括.jsp。斜杠星【/*】表示所有请求,也包括.jsp!
(1)默认配置
解释:此配置作用下,SpringMVC的配置文件默认位于WEB-INF下,默认名称为<servlet-name>中的名称-servlet.xml,例如,以下配置所对应SpringMVC的配置文件位于WEB-INF下,文件名为springMVC-servlet.xml
注:但是我们都是统一把配置文件放到resources中去,所以这种方式不好!
- <!-- 配置SpringMVC的前端控制器,对浏览器发送的请求统一进行处理 -->
- <servlet>
- <servlet-name>springMVC</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>springMVC</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
(2)扩展配置方式
解释:可通过init-param标签初始化参数,使用contextConfigLocation【上下文配置路径】指定SpringMVC配置文件路径;使用classpath:配置文件名称来配置置SpringMVC配置文件的具体位置和名称。
注:classpath就是表示java路径或者resources下面的路径!
解释:通过load-on-startup标签设置SpringMVC前端控制器DispatcherServlet的初始化时间。作为框架的核心组件,在启动过程中有大量的初始化操作要做而这些操作放在第一次请求时才执行会严重影响访问速度,因此需要通过此标签将启动控制DispatcherServlet的初始化时间提前到服务器启动时。
- <?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">
- <!--注册SpringMVC框架-->
- <servlet>
- <servlet-name>springmvc</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!--引入springmvc的核心配置文件-->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- <!--将前端控制器DispatcherServlet的初始化时间提前到服务器启动时-->
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>springmvc</servlet-name>
- <!--指定拦截什么样的请求
- 例如:http://localhost:8080/demo.action
- -->
- <url-pattern>*.action</url-pattern>
- <url-pattern>/</url-pattern> <!---拦截所有-->
- </servlet-mapping>
- </web-app>
第五步:添加springmvc.xml配置文件:指定包扫描,添加视图解析器
①使用InternalResourceViewResolver(内部资源视图解析器),指定资源的前缀和后缀!
- <?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"
- 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">
- <!--配置包扫描-->
- <context:component-scan base-package="com.bjpowernode.controller"/>
- <!--配置视图解析器-->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!--前缀-->
- <property name="prefix" value="/admin/"/>
- <!--后缀-->
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
视图解析器配置的作用就是跳转页面,跳转到/admin/xxx.jsp页面,这里就假设跳转到main.jsp文件,就需要先创建一个admin目录,然后在目录中在创建一个mian.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>Title</title>
- </head>
- <body>
- <h1>main.........</h1>
- </body>
- </html>
②也可以使用配置Thymeleaf视图解析器(依赖前面已经引过了),指定前缀和后缀!
- <!-- 配置Thymeleaf视图解析器 -->
- <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
- <!--表示有其它控制器优先使用这个-->
- <property name="order" value="1"/>
- <property name="characterEncoding" value="UTF-8"/>
- <property name="templateEngine">
- <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
- <property name="templateResolver">
- <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
- <!-- 视图前缀 -->
- <property name="prefix" value="/WEB-INF/templates/"/>
- <!-- 视图后缀 -->
- <property name="suffix" value=".html"/>
- <property name="templateMode" value="HTML5"/>
- <property name="characterEncoding" value="UTF-8" />
- </bean>
- </property>
- </bean>
- </property>
- </bean>
此时需要在WEB-INF下创建一个templates,然后再创建一个index.html
注:此时要index.html要加上thymeleaf命名空间,并且是放到了webapp下面直接访问肯定是访问不到,所以需要转发的方式进行访问!
- <!DOCTYPE html>
- <!--引入thymeleaf命名空间-->
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset=" UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>首页</h1>
- </body>
- </html>
第六步:删除index.jsp页面(不合规范),并新建,发送请求给服务器
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>Title</title>
- </head>
- <body>
- <%--发送请求--%>
- <a href="${pageContext.request.contextPath}/demo.action">访问服务器</a>
- </body>
- </html>
第七步:创建类似于Servlet功能的处理器action
分析:以前的Servlet的规范,protected void doPost
(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}必须是这种形式的
action中所有的功能实现都是由方法来完成的,action方法的规范:
①访问权限是public;
②方法的返回值任意;
③方法名称任意;
④方法可以没有参数,如果有可是任意类型;
⑤要使用@RequestMapping注解来声明一个访问的路径(名称);
注:如果不使用springMVC时,@Controller注解和@Service、@Component、@Repository注解没有什么差别的,但如果使用了springMVC,@Controller注解就被赋予了特殊的含义!spring会遍历上面扫描出来的所有bean,过滤出那些添加了注解@Controller的bean,将Controller中所有添加了注解@RequestMapping的方法解析出来封装成RequestMappingInfo存储到RequestMappingHandlerMapping中的mappingRegistry。后续请求到达时,会从mappingRegistry中查找能够处理该请求的方法。
- package com.bjpowernode.controller;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- @Controller // 交给spring容器去创建对象
- public class DemoAction {
- /**
- * 1)访问权限是public
- * 2)方法的返回值任意
- * 3)方法名称任意
- * 4)方法可以没有参数,如果有可是任意类型
- * 5)要使用@RequestMapping注解来声明一个访问的路径(名称)
- */
- @RequestMapping("/demo")
- public String demo(){
- System.out.println("服务器被访问到了......");
- // 根据返回的main,就可以跳转到/admin/main.jsp页面上
- return "main";
- }
- }
第八步:测试
首先访问的是index.jsp,当点击超链接时,会跳转到DemoAction(类似于Servlet的功能),然后返回一个“main”字符串
根据返回的字符串“mian”,核心处理器DispatcherServlet会根据注册的springmvc.xml文件里面的视图解析器:加上前缀和后缀,完成路径的拼接:/admin/main.jsp,最终完成页面的跳转
补充:当然也可以使用thymeleaf【前面配置都已经配置好了】
编写controllelr
- package com.zl.controller;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- @Controller
- public class HelloController {
- @RequestMapping("/")
- public String index(){
- return "index";
-
- }
- }
开启Tomcat,当访问根目录时会进行跳转到index.htm
注:此时过过引入了logback-classic依赖,还会输出一下请求处理的信息
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.2.11</version>
- </dependency>
通过index.jsp在访问其他页面目标程序
原来的写法:如果使用的是.jsp;可以使用超链接+EL表达式获取上下文路径/访问的路径
<a href="${pageContext.request.contextPath}/target" ></a>
现在的写法:现在使用的是html的形式,不能使用EL表达式,怎么办呢?
注:首先属性名用【th:】去修饰,属性值放到@{"/target"}的形式,检测到是绝对路径/target会在前面加上下文路径bank。
<a th:href="@{/target}" ></a>
编写controller
- @RequestMapping("/target")
- public String toTarget(){
- return "target";
- }
编写WEB-INF/templates下的target.html
- <!DOCTYPE html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>HelloWorld</h1>
- </body>
- </html>
总结:浏览器发送请求,若请求地址符合前端控制器的url-pattern(该请求我们写的是"/",表示匹配除.jsp的任何形式的请求),该请求就会被前端控制器DispatcherServlet处理。前端控制器会读取SpringMVC的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析,加上前缀和后缀组成视图的路径,通过Thymeleaf对视图进行渲染,最终转发到视图所对应页面!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。