是Spring框架中的一个模块,又叫spring web mvc框架的一部分,是在 Spring3.0 后发布的。 //界面层
说明他是使用spring核心技术做web开发,springmvc内部使用mvc架构模式
SpringMVC也是一个容器,管理对象的,使用IoC核心技术-------管理界面层中的控制器对象(底层是servlet对象)
// 所以springmvc容器创建一种叫控制器的对象,该对象代替servlet行使控制器的角色
springmvc底层是servlet,以servlet为核心,接受请求、处理请求
用户请求--->springmvc---->spring----->mybatis---->数据库
(mvc) (service层) (dao层)
SpringMVC中的核心Servlet-----DispatcherServlet: 继承自:HttpServlet
是框架中的一个servlet对象,负责接受请求,响应处理结果。也叫前端控制器、中央调度器
注解的 SpringMVC 程序: //springmvc主要使用注解的方式,创建控制器对象,处理请求
1)Maven新建web项目
2)加入spring-webmvc依赖(springmvc框架依赖)、servlet依赖、jackson依赖(框架处理json默认使用jackson)
3)在web.xml中声明springmvc核心对象DispatcherServlet // org.springframework.web servlet包下
1.一个servlet对象,继承自:HttpServlet,也叫前端控制器、中央调度器 Front controller
2.作用:a.在servlet的init()方法中创建springmvc中的容器对象----接受springmvc配置文件的Java对象,即处理器对象
b.作为servlet,接受请求web.xml:部署描述符文件,给Tomcat服务器用的,在服务器启动时读取该文件,根据文件声明创建各种对象
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0" metadata-complete="true"> <!--声明servlet核心对象 中央调度器 直接访问该地址,未找到文件 /WEB-INF/<servlet-name>-servlet.xml 错误原因:在servlet的init方法中,创建容器对象webApplicationContext,创建时需要传入配置文件,文件默认路径:/WEB-INF/<servlet-name>-servlet.xml 所以需要在WEB-INF目录下创建<servlet-name>名-servlet.xml配置文件--> <servlet> <servlet-name>名</servlet-name> <servlet-class>org.springframework.web servlet.DispatcherServlet</servlet-class> <!--可以自定义配置文件的路径--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:xxxx.xml类路径下的xxxspringmvc配置文件</param-value> </init-param> <!--启动时会创建这个Servlet实例,即是否在 Web 服务器启动时调用执行该Servlet的init()方法,而不是在真正访问时才创建。--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>名</servlet-name> <url-pattern>*.xxx</url-pattern> 表示以xxx结尾的动态资源 <url-pattern>/</url-pattern> 该中央调度器变成default身份,能处理静态资源和为映射的请求 </servlet-mapping> </web-app>
若设置了/,没有设置静态资源请求的控制器对象,则浏览器会出现404不能访问静态资源,因为没有对应的控制器对象去使用。 所以需要处理静态资源的访问工作
方式一:在springmvc配置文件中添加 <mvc:default-servlet-handler/>,那么框架会在运行时会加入DefaultServletHttpRequestHandler 处理器对象去处理静态资源访问
DefaultServletHttpRequestHandler对象把接受的静态资源地址转发给Tomcat的default-----------------------------缺点:依赖于Tomcat服务的default
注意:该标签和@RequestMapping有冲突,所以要在该标签之前加上<mvc:annotation-driven/>
方式二:在springmvc配置文件中添加 <mvc:resources/>,那么框架会创建ResourceHttpRequestHandler控制器对象,使用该对象来处理静态资源的访问
推荐使用:不依赖服务器
4)创建一个jsp发起请求
5)创建一个普通的类,作为控制器使用(代替之前的servlet) //创建处理器
1.在类上面加入@Controller注解 (创建控制器对象的) //表示创建出此类对象,放入到springmvc容器当中
2.在类中定义方法,方法上加上@RequestMapping注解(请求映射)------控制器方法 //该方法处理处理请求,相当于servlet的doGet、doPost方法
a.形参表示请求中的参数
b.返回值表示本次请求的处理结果 (数据和视图)
6)创建作为结果的JSP页面:就是jsp页面,放入WEB-INF文件下,建个目录存放。这样是受保护的,浏览器就访问不了了,在程序中可以访问
7)springMVC配置文件(spring一样)
1.声明组件扫描器,指定@Controller注解所在的包
2.声明视图解析对象 :帮助处理视图,即转发请求视图页面时若只是名字不同,可以用一定格式代替来通用所有的视图页面
配置了视图解析器,使用文件名作为视图名使用----->视图逻辑名springmvc框架配置文件:声明框架创建的项目中的各种对象,主要是创建控制器对象
<?xml version="1.0" encoding="UTF-8"?> <!--suppress ALL --> <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="注解所在的包名"/> <!--声明视图解析器对象--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀:指定视图文件的路径--> <property name="prefix" value="/WEB-INF/目录"/> <!--后缀:指定视图文件的扩展们--> <property name="suffix" value=".jsp"/> </bean> <!--声明注解驱动:创建HttpMessageConverter接口的7个实现类对象 处理<mvc:default-servlet-handler/>与@RequestMapping的冲突--> <mvc:annotation-driven/> <!--处理静态资源的访问工作:方式一--> <mvc:default-servlet-handler/> <!--处理静态资源的访问工作:方式二 推荐--> <!--mapping:访问静态资源的url地址,可以使用通配符** **表示任意目录和目录的资源名称 location:静态资源在项目中的目录--> <mvc:resources mapping="/xxx/**" location="/xxx/"/> 开头的/表示web项目的根目录 可以配置多个<mvc:resources /> <!--一句话设置静态资源:在项目下建立static目录,在该目录下建立html、images等目录,资源放在这些目录--> <mvc:resources mapping="/static/**" location="/static/"/> </beans>
8)使用逻辑视图名称: //即在处理器的方法中
配置文件加载的顺序:
1)Tomcat启动:读取web.xml,根据文件说明创建对象-------DispatcherServlet对象,执行init(),在init方法中又执行springMVC容器对象的创建
2)springmvc框架:创建容器对象需要读取 springmvc配置文件------使用组件扫描时遍历该包下的所有类,找到@Controller、@RequestMapping就能创建控制器对象
有了控制器对象,就能执行里面的方法
3)用户发起请求----DispatcherServlet(里面有容器对象,容器对象里面有里面有控制器对象)----调用对应的方法
springmvc请求的处理过程:
用户发起请求--->Tomcat接受请求--->DispatcherServlet中央调度器(分配给)--->处理器(对应的处理器的方法最后返回一个ModelAndView对象)--->ModelAndView对象显示给用户
简化: 请求-----------------------------------DispatcherServlet-----------------------------------处理器 //多了DispatcherServlet功能,可以在请求中增加功能Servlet请求的处理过程:
请求---------------------------------------Tomcat接受请求-------------------------------------Servlet //少了DispatcherServlet功能
springmvc可以在处理器中定义不同方法分别处理请求路径,是处理器可以有多个方法,一个方法可以对应多个请求路径的处理 //这样就可以有多个请求处理
Servlet是一个servlet对象对应某一种请求的相同处理
SpringMVC 的 MVC 组件:
C:前端控制器Front Controller、后端控制器Controller
SpringMVC注解式开发
请求映射
@Controller注解 //创建控制器对象的 位置:作为控制器的类
//表示创建出此类对象,放入到springmvc容器当中
@RequestMapping 位置:1)作为控制器的类的方法上 2)作为控制器的类上|
作用:把指定的请求交给指定的方法处理,作用相当于<url-pattern>
属性:value 1)值为字符串数组:请求中的url地址,是唯一值,以/开头带代根路径--------注解在方法上
2)表示所有请求地址的公共前缀,相当于模块名称 ----------------------------------注解在类上 //这样在指定路径时只写剩下的就可以了method 请求方式 (使用RequestMethod类的枚举值 如: RequestMethod.GET) //没有该属性则请求方式不限制
produces 指定context-type的值,即编码方式 该值一般为"text/plain;charset=utf-8"
该方法的返回值: 返回值表示本次请求的处理结果 -----------ModelAndView、String、void、Object
方法的返回值代表本次请求的处理结果:
1)方法返回值ModelAndView类对象(数据和视图)
new ModelAndView() //方法:
.addObject("key值",obj) 用于向其 Model 中 添加数据。Model 的底层为一个 HashMap
1 .setViewName("/根下的xxx/xxx.jsp") 指定视图,参数是视图的完整路径
2 .setViewName("逻辑视图名称") 指定视图。使用视图逻辑名,框架会使用配置文件中视图解析器的前后缀来拼接作为完整路径
***当框架调用完该方法后,得到返回值ModelAndView对象,框架会在后续的处理逻辑中处理该对象的数据和视图。
对数据执行request对象.setAttribute("key值",obj)把数据放入到request对象的作用域
对视图执行forward转发操作。等同于 request对象.getRequestDispather("/根下的xxx/xxx.jsp").forward(……)2)方法返回值String (视图)
返回值:1.完整路径
2.逻辑名称
对视图执行forward转发操作。3)方法返回值void (没有数据和视图)
做ajax请求处理,可以使用HttpServletResponse对象输出数据,响应Ajax请求4)方法返回值Object (数据)
用来返回数据,Ajax请求要的就是数据源,所以一般会用来响应Ajax请求
Ajax请求中,一般需要从服务器返回json格式的字符串,经常要处理Java对象转换成json对象,而且还需要输出数据响应Ajax的请求,所以框架提供了:转换、输出
一、HttpMessageConverter接口:消息转化器------作用:1.请求的数据转为Java对象 2.把控制器方法返回的对象转为json、xml、text、二进制等不同格式数据
方法:boolean canRead(Class<?> clazz,MediaType mediaType) //检查clazz类的对象,能否转为mediaType所表示的数据格式,能转返回true,返true就调用read()方法
MediaType:媒体类型,表示在互联网中应用程序交换数据时数据的格式
T read(Class<? extends T> clazz,HttpInputMessage inputMessage)inputMessage) //将请求中的数据,转为clazz表示的对象
boolean canWrite(Class<?> clazz,MediaType mediaType) //检查clazz这种数据类型能否转成mediaType所表示的数据格式,能转返true,则调用Write()方法
void write(T t,MediaType contnetType,HttpOutputMessgae outputMessage) //将 T 类型的对象按照contentType格式转为json或xml
//这四个方法都是框架自己根据数据类型调用
实现类:MappingJackson2HttpMessageConverter 用Jackson工具库中的objectMapper把Java对象转为json数据格式
StringHttpMessageConverter 把字符串类型的数据,进行格式转换和编码
使用:框架根据控制器方法的返回值来自动查找实现类
//默认情况下springmvc使用了HttpMessageConverter接口的4个实现类,其中包括了StringHttpMessageConverter
//所以需要再springmvc配置文件中加入注解驱动的标签<mvc:annotation driven/> 加入该标签后springmvc项目启动后,会创建该接口的7个实现类对象
二、@ResponseBody 注解 再控制器方法上 --------把数据通过HttpServletResponse对象输出给浏览器1.框架根据控制器方法的返回值类型找到对应的HttpMessageConverter接口的实现类
2.使用实现类指定write(),把控制器方法返回值转为要求格式的数据
3.框架使用@ResponseBody注解把转为要求格式的数据输出到浏览器
1.若返回的对象为List集合,转json则为json对象的数组
2.方法返回值String(数据),发给浏览器的是字符串 //带@ResponseBody注解则为数据,不带注解则为视图
//使用的实现类是StringHttpMessageConverter,而该类使用的是"text/plain;charset=IOS-8859-1" 编码方式作为默认字符集,所以要在RequestMapping 注解中声明编码方式
该方法的形参:方法(HttpServletRequest request,HttpServletResponse response,HttpSession session,参数……) //形参可以随便写哪个都可以,框架会赋值数据
- 逐个接受:只要保证URL请求参数名-----与----该请求处理方法的形参名相同。可以直接在方法中使用
底层:框架使用request对象接受对象:request.getParameter(形参名),在中央调度器内部调用方法时按照名称传入(会转换成形参类型)参数
解决POST方式乱码问题:使用框架给的过滤器------spring web 5 2 5 .RELEASE.jar 的org.springframework.web.filter 包下的 CharacterEncodingFilter 类。
注意:参数最好使用包装类型,因为能接受空值的情况null。
框架可以使用String到数值类型的转换
POST请求由乱码问题---使用字符集过滤器<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0" metadata-complete="true"> <!--声明过滤器,由框架提供,为了解决POSt乱码问题--> <filter> <filter-name>自定义名,一般为小驼峰类名</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> <!--给过滤器属性赋值--> <init-param> <!--强制请求对象request使用encoding的编码方式--> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!--给过滤器属性赋值--> <init-param> <!--强制响应对象response使用encoding的编码方式--> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>对应上面的名</filter-name> <!--/*表示所有的请求都结果过滤器处理--> <filter-pattern>/*</filter-pattern> </filter-mapping> </web-app>
- 使用对象接受:在控制器方法的形参是一个Java对象,使用Java对象属性来接受参数值 //形参可以是多个对象
要求:1)Java对象的属性名---与----请求参数名通过一致 2)Java类有无参构造、set方法
框架调用Java类的无参构造创建Java对象,再调用对象的set方法设置同名的参数
@RequestParam 逐个接收参数时--------------url请求参数名与控制器方法形参的名称不一样时 位置:形参前面
属性value 请求中的参数名 //方法名( 注解 形参,@RequestParam(value="请求参数名",required=false) 形参,……)
required 布尔值,默认值true:请求中必须由参数
SSM整合开发:ssm
SpringMVC是spring的一个模块(一部分),可以一起用
spring与mybatis整合
3个框架对应三层架构3层:
springMVC 视图层
spring 业务层
mybatis 持久层
把对象交给容器管理,让容器创建项目中使用的Java对象,现在有2个容器
- spring容器:管理service、dao等对象,是业务层对象的容器
在web.xml中声明了监听器ContextLoaderListener,创建spring的容器对象WebApplicationContext,在创建对象时会读取spring配置文件将bean标签或注解创建service、dao对象放入容器- springMVC容器:管理控制器对象的,是视图层对象
在webl.xml声明了中央调度器DispatcherServlet,在servlet的init()方法中创建了容器对象WebApplicationContext,在创建对象时会读取springMVC配置文件将@Controller注解创建控制器对象,放到容器- 2个容器的关系:在设计上,springMVC容器对象是spring容器对象的子容器。
相当于Java的继承关系,子容器可以访问父容器的对象,子容器的控制器对象能访问父容器的service对象
- 数据库表
- 创建maven项目
- 修改pom.xml,加入依赖:spring、springmvc、mybatis、mybatis-spring、MySQL驱动、druid、jackson、拷贝文件的插件
- 写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"> </web-app>
- 声明spring监听器ContextLoaderListener创建spring容器对象
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
- 声明springmvc中央调度器DispatcherServlet创建springmvc容器对象
<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/dispatcherServlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
- 声明字符集过滤器CharacterEncodingFilter 解决post请求的乱码问题
<filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encodeing</param-name> <param-value>utf-8</param-value> </init-param> </init-param> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- 创建程序中的包:实体类包domain、dao、service、controller(控制器对象的包)
- 写spring、springmvc、mybatis的配置文件:在项目的resources目录下建立conf目录,文件写在里面统一管理
- spring配置文件 applicationContext.xml
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明service、dao、工具类、事务配置--> <!--------------------------------------service-------------------------------> <!-- 扫描service相关的bean --> <context:component-scan base-package="service包" /> <!--------------------------------------dao-------------------------------> <!-- 1.关联数据库文件 --> <context:property-placeholder location="classpath:conf/jdbc.properties"/> <!-- 2.数据库连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" init-method="inti" destroy-method="close"> <!-- 配置连接池属性 --> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 3.配置SqlSessionFactory对象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 注入数据库连接池 --> <property name="dataSource" ref="dataSource"/> <!-- 配置MyBaties全局配置文件:mybatis-config.xml --> <property name="configLocation" value="classpath:conf/mybatis.xml"/> </bean> <!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 注入sqlSessionFactory --> <property name="sqlSessionFactoryBeanName" value="factory"/> <!-- 给出需要扫描Dao接口包 --> <property name="basePackage" value="dao包"/> </bean> <!--事务配置--> <import resource="spring-mvc.xml"/> <import resource="spring-dao.xml"/> <import resource="spring-service.xml"/> </beans>
- springmvc配置文件 dispatcherServlet.xml
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明controller、视图解析器等web开发中的对象--> <!-- 注解驱动--> <mvc:annotation-driven/> <!--静态资源过滤--> <mvc:default-servlet-handler/> <!-- 扫描包--> <context:component-scan base-package="controller包"/> <!--视图解析器--> <!-- 配置jsp 显示ViewResolver视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
- mybatis主配置文件 mybatis.xm
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- configuration核心配置文件--> <configuration> <!--设置日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--配置数据源,交给spring做--> <!--扫描实体类包下的实体类,并取别名--> <typeAliases> <package name="实体类包"/> </typeAliases> <!--注册mapper:加载dao包中的所有mapper文件--> <mappers> <package name="dao包"/> </mappers> </configuration>
- 数据库属性配置文件:jdbc.properties
jdbc.url=jdbc:mysql://localhost:3306/数据库名 jdbc.username=xxx jdbc.password=xxx
- 写Java代码,实体类、dao接口和mapper文件、service类、controller类。使用注解声明对象、赋值
controller对象:私有成员----------用service对象作为私有属性 //使用注解自动注入service对象,这样在控制器对象的方法中就可以调用service对象了
service对象:私有成员----------用dao对象作为私有属性 //使用注解自动注入dao对象,这样在service对象的方法中就可以调用dao对象了- 创建视图文件:各种jsp
页面中路径问题:是否有/
1)无协议开头的:相对地址,单独使用不能表示某个资源,相对地址必须和参考地址在一起才能表示一个资源的完整地址,才可以访问
有无/时,参考地址是不同的:
<a href="/aaa/bbb"> 有/时:参考地址是服务器地址http://location:8080/ 地址组成:参考地址+herf相对地址------------还缺少项目名访问路径:项目名
<a href="aaa/bbb"> 无/时:会把资源去掉,剩下的未参考路径。 完整路径:参考路径+href相对地址
例如:
当前页面:http://location:8080/项目名/xxxx/index.jsp
资源名称:index.jsp
参考路径:当前资源的访问路径 http://location:8080/项目名/xxxx/
2)协议开头的:绝对地址,唯一的,能直接访问
<a href="http:www.baidu.com">
当无/时:访问的路径有深度时,会出现路径错误的现象------解决:在jsp页面上
方式一:<a href="${pageContext.request.contextPath}aaa/bbb"> //${pageContext.request.contextPath}/aaa/bbb}表达式代表上下文context path,即访问项目的路径
//注意加的是${pageContext.request.contextPath}/aaa/bbb}/
优点:好理解 缺点:每个链接都一个一个加太麻烦
方式二:固定当前页面中没有/开头地址的参考地址 在html中:head标签里加上base标签:<base href="自定义的参考地址">
动态变化的:
指定路径:<% String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/"; %>
指定base 标签 : <base href="<%=basePath%>">
有/时:缺少项目名访问路径:项目名-----解决:
在路径前加入el表达式${pageContext.request.contextPath} <a href="${pageContext.request.contextPath} /aaa/bbb">
springMVC核心技术
转发:控制器方法返回ModelAndView对象实现转发forward //forward不和视图解析器一同工作,就当项目中没有视图解析器
显示使用forward指定转发路径:ModelAndView对象.setViewName("forward:视图完整路径---项目/根路径下")
重定向:控制器方法返回ModelAndView对象实现转发forward //redirect不和视图解析器一同工作,就当项目中没有视图解析器
ModelAndView对象.setViewName("redirect:视图完整路径---项目/根路径下")
框架提供的重定向功能:实现2次请求之间的数据传递:ModelAndView对象.addObject("key值",obj) ,会转为简单类型数据的字符串形式,添加到重定向路径后面作为参数
在目标页面可以使用${param.参数名}来获取参数的值
重定向不能访问WEB_INF
框架的集中处理异常:把各个Controller中抛出的异常集中到一个地方处理。处理异常的叫做异常处理器
框架使用2个注解完成异常的集中处理
@ExceptionHandler 注解 位置:方法上
表示此方法可以处理某个类型的异常,当异常发生时执行这个方法
属性value 值为class数组,用于指定该注解的方法所要处理的异常类 //没有该属性表示处理任何类型的异常
@ControllerAdvice注解 位置:类的上面
表示这个类是一个异常处理类,里面有异常的处理方法,相当于aop中的@Advice,可以看作控制器增强,给Controller类增加异常(切面)的处理功能
- 创建一个普通类,类里定义方法,在类上加@ControllerAdvice注解、方法上加@ExceptionHandler 注解
- 方法:有个参数(Exception e) 表示抛出的异常对象
- 方法返回值:可以是ModelAndView对象
- 在springmvc配置文件中声明组件扫描器,找到ControllerAdvice注解的包名 <context:component-scan base-package="异常类的包"/>
- 声明注解驱动 <mvc:annotation-driven/>
拦截器:是springmvc框架中的一个对象,需要实现 HandlerInterceptor 接口。拦截用户的请求-------即拦截到Controller的请求
作用:拦截用户请求,可以预先对请求做处理,根据处理结果决定是否执行Controller。也可以把多个Controller公用的功能定义到拦截器而该接口中含有三个默认方法: //默认方法即可以选择去实现
- preHandle(HttpServletRequest,HttpServletResponse, Object handler) 预先处理请求的方法
- 参数三:handler:表示被拦截的控制器对象Controller
- 返回布尔值
- true:请求正确,可以被Controller处理
- false:请求不能被处理,控制器方法不能执行,请求到此截至
- 执行时间:在控制器方法之前先执行的 //所以可以决定请求是否执行
- postHandle(HttpServletRequest,HttpServletResponse, Object handler,modelAndView ) 后处理方法
- 参数三:handler:表示被拦截的控制器对象Controller
- 参数四:ModelAndView对象:控制器方法的返回值
- 执行时间:控制器方法执行执行 //所以能够获取控制器方法的执行结果,可以修改这个执行结果---改数据、视图(请求的二次处理)
- afterCompletion(HttpServletRequest,HttpServletResponse, Object handler, Exception ex) 最后执行的方法
- 参数三:handler:表示被拦截的控制器对象Controller
- 参数四:Exception:异常对象
- 执行时间:在请求处理完成后执行 (请求处理完成的标志是视图处理完成-----对视图执行forward操作之后)
- 可以做程序最后要做的工作。如:释放内存、清理变量
- 方法执行的条件:
- preHandle方法必须执行
- preHandle方法必须返回true
单拦截器:请求------>preHandle---->Controller方法----->postHandle------>afterCompletion
多拦截器:请求------>preHandle1---->preHandle2---->Controller方法----->postHandle2------>postHandle1------>afterCompletion2------>afterCompletion1
多个拦截器串在一条链上,框架中使用:HanderExecutionChain类(处理器执行链)来表示执行链条
//拦截器声明的顺就是拦截器的执行顺序
特点:
- 分类:1)相同拦截器 2)自定义拦截器
- 一个项目中可以有多个拦截器
- 拦截器侧重拦截用户请求
- 拦截器是在请求处理之前先执行的
拦截器的定义:
- 创建实现类,实现HandlerInterceptor接口,实现接口方法
- 在springmvc配置文件中声明拦截器对象,并指定拦截的url地址
<!--声明拦截器--> <mvc:interceptors> <!--声明第一个拦截器 拦截器声明的顺就是拦截器的执行顺序--> <mvc:interceptor> <!--指定拦截器拦截的拦截地址 path:url地址,可以使用**、/项目根目录--> <mvc:mapping path="/**" /> <!-- 排除拦截的地址 --> <mvc:exclude-mapping path=""/> <!--指定使用的拦截器--> <bean class="拦截器实现类的全限定名" /> </mvc:interceptor> <!--声明第二个拦截器--> <!--声明第三个拦截器--> </mvc:interceptors>
拦截器与过滤器对比:
拦截器是springmvc框架中的对象。过滤器是servlet中的对象
拦截器对象是框架容器创建的。过滤器对象是Tomcat容器创建的
拦截器是侧重对请求做验证处理的,可以截断。过滤器侧重对request、response对象的属性值,参数设置值的
拦截器的执行时间有3个。过滤器在请求之前
拦截器是拦截Cotroller动态资源的,过滤器可以过滤所有请求(动态、静态资源)
拦截器和过滤器一起执行:过滤器---中央调度去-----拦截器----控制器方法
Springmvc 框架内部执行流程
- 浏览器提交请求到中央调度器
- 中央调度器直接将请求转给处理器映射器。
- 处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行链后返回给中央调度器。
处理器映射器:springmvc框架中的对象,需要实现HandlerMapping接口
作用:从springmvc容器中获取控制器对象Controller,把控制器对象和拦截器对象放到处理器执行链对象中,保存,并返回给中央调度器。- 中央调度器根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器。
处理器适配器:springmvc框架中的对象,需要实现HandlerAdapter接口
作用:执行控制器的方法- 处理器适配器调用执行处理器。
- 处理器将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给处理器适配器。
- 处理器适配器直接将结果返回给中央调度器。
- 中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象。
视图解析器:springmvc框架中的对象,需要实现ViewResolver接口
作用:处理视图,组成视图完整路径。创建View类型的对象(代表视图的)- 视图解析器将封装了的视图对象返回给中央调度器
- 中央调度器调用视图对象(View)的方法,让其自己进行渲染,即进行数据填充,形成响应对象。 //将Model中的数据放入request作用域。执行request.setAttribute()
- 中央调度器响应浏览器。 //,对视图执行forward转发行为,
中央调度器是创建容器对象的
查看DispatcherServlet类,是一个servlet。 //DispatcherServlet------继承自-----FrameworkServlet-----继承自-------HttpServlet
1.HttpServlet有方法init()
2.在init()方法中调用HttpServlet子类的initServletBean()方法
3.在initServletBean()方法中调用initWebApplicationContext()方法
initWebApplicationContext()方法创建容器对象
在方法内获取全局作用域对象,并把创建的容器对象通过setAttribute()放入全局对象域对象