1.Web、MVC、WebMVC概述
完成一次web请求的过程
Web浏览器发起请求
Web服务器接收请求并处理请求,最后产生响应(一般为html)。
web服务器处理完成后,返回内容给web客户端,客户端对接收的内容进行处理并显示出来。
从这里可以看出,在web中,都是web客户端发起请求,web服务器接收处理请求并产生响应。
一般Web服务器是不能主动通知Web客户端更新内容。虽然有些技术可以帮我们实现这样的效果,如服务器推技术(Comet)、还有HTML5中的websocket等。
2.MVC模型(Model-View-Controller)
是一种架构型的模式,本身不引入新功能,只是帮助我们将开发的代码结构,组织的更加合理。
Model(模型)
数据模型,提供要展示的数据,因此包含数据和行为,行为是用来处理这 00些数据的。不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是数据由实体类或者javabean来提供,行为由service层来提供.
View(视图)
负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器)
接收用户请求,委托给模型进行处理,处理完毕后把返回的模型数据交给给视图。也就是说控制器在中间起到一个调度的作用。
3.SpringWebMVC概述(SpringMVC)
1)SpringWebMVC简称SpringMVC
SpringMVC就是Spring框架提供的一个模块,通过实现MVC模式来很好地将数据、业务与展现进行分离,SpringMVC框架的目的是要简化我们日常的Web开发。
SpringMVC框架跟其他的WebMVC框架一样,都是请求驱动,并且设计围绕一个能够分发请求到控制器以及提供其他加快web应用开发功能的核心Servlet(叫做DispatcherServlet,即前端控制器)。Spring的DispatcherServlet实现比其他框架中还要多的功能。它和spring的ioc容器完全整合,并且允许使用spring中其他的所有功能。
SpringMVC框架设计的一个核心的原则就是"开闭原则",对扩展开放,对修改关闭.所以SpringMVC框架中很多方法都是final的,不允许用户随意覆盖,但是却提供给用户很多可扩展的机制。SpringMVC目前已经成为非常流行的web应用的框架。
2)SpringMVC框架的获取
由于SpringMVC是Spring框架中的一个模块,所以我们下载Spring框架即可,因为里面包含了Spring框架的各个模块的相关东西,当然也包含了SpringMVC的(jar包、API文档、源代码)
3)SpringMVC框架的核心组件
1.DispatcherServlet: 前端控制器,用来过滤客户端发送过来,想要进行逻辑处理的请求。
2.Controller/Handler: 控制器/处理器。开发人员自定义,用来处理用户请求的,并且处理完成之后返回给用户指定视图的对象。
3.HandlerMapping: 处理器映射器。DispatcherServlet接收到客户端请求的URL之后,根据一定的匹配规则,再把请求转发给对应的Handler,这个匹配规则由HandlerMapping决定。
4.HandlerAdaptor:处理器适配器。处理器适配器用来适配每一个要执行的Handler对象。通过HandlerAdapter可以支持任意的类作为处理器
5.ViewResolver:视图解析器。Handler返回的是逻辑视图名,需要有一个解析器能够将逻辑视图名转换成实际的物理视图。而且Spring的可扩展性决定了视图可以由很多种,所以需要不同的视图解析器,解析不同的视图。但是一般由jsp充当视图的情况居多
4.SpringMVC框架在项目中的搭建
第一步:构建Web项目
第二步:导入所需jar包
第三步:配置前端控制器DispatcherServlet
第四步:编写Controller控制器(也称为Handler处理器)
第五步:配置处理器映射器(可省去,有默认配置)
第六步:配置处理器适配器(可省去,有默认配置)
第七步:配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
第八步:配置处理器
5.Controller接口及其实现类
Controller是控制器/处理器接口,此处只有一个方法handleRequest,用于进行请求的功能处理(功能处理方法),处理完请求后返回ModelAndView对象(Model模型数据部分 和 View视图部分)。
6.处理器拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
1)常见应用场景
1、日志记录
2、权限检查
3、性能监控
4、通用行为 例如读取用户cookie
5、OpenSessionInView 和延迟加载有关例如在Hibernate中,在进入处理器前打开Session,在完成后关闭Session。
等
2)拦截器接口
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;
}
preHandle方法
预处理回调方法,实现处理器的预处理,第三个参数为处理器(本次请求要访问的那个Controller)
返回值:true表示继续流程(如调用下一个拦截器或处理器)
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应
postHandle方法
后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过ModelAndView对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion方法
整个请求处理完毕回调方法,即在视图渲染完毕时回调
3)拦截器适配器
有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor 接口的话,三个方法必须实现,不管你需不需要,此时spring 提供了一个HandlerInterceptorAdapter 适配器(适配器模式),允许我们只实现需要的回调方法。
在HandlerInterceptorAdapter中,对HandlerInterceptor 接口中的三个方法都进行了空实现,其中preHandle方法的返回值,默认是true
4)测试一个拦截器
拦截器代码:
public class MyInterceptor1 extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("MyInterceptor1 preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1 postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("MyInterceptor1 afterCompletion");
}
}
配置文件:(注意此配置在文件中的配置顺序,要写在配置文件的上面)
<bean name="handlerInterceptor1" class="com.briup.web.interceptor.MyInterceptor1"/>
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
</list>
</property>
</bean>
访问一个测试的Controller查看结果:
MyInterceptor1 preHandle
TestController执行
MyInterceptor1 postHandle
MyInterceptor1 afterCompletion
7.基于注解的SpringMVC
1)用于支持注解的配置
在Spring中,
处理器类可以使用 @Controller注解
业务逻辑层可以使用 @Service注解
数据持久层可以使用 @Repository注解
2)基于注解的Controller
使用注解后,就不需要再实现特定的接口,任意一个javaBean对象都可以当做处理器对象,对象中任意一个方法都可以作为处理器方法。
只需
在类上加上 @Controller注解
方法上加上 @RequestMapping注解
8.Spring2.5中引入注解对处理器(handler)支持
@Controller
用于标识是处理器类;
@RequestMapping
请求到处理器功能方法的映射规则;
@RequestParam
请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute
请求参数到命令对象的绑定;
@SessionAttributes
用于声明session 级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session 中
@InitBinder
自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
9.Spring3引入了更多的注解,其中包含了对RESTful架构风格的支持
@CookieValue
cookie数据到处理器功能处理方法的方法参数上的绑定;
@RequestHeader
请求头数据到处理器功能处理方法的方法参数上的绑定;
@RequestBody
请求的body体的绑定
@ResponseBody
处理器功能处理方法的返回值作为响应体
@ResponseStatus
定义处理器功能处理方法/异常处理器返回的状态码和原因;
@ExceptionHandler
注解式声明异常处理器;
@PathVariable
请求URI 中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;
10.URL路径映射
1)普通URL路径映射
@RequestMapping(value="/test")
@RequestMapping("/hello")
注解中只出现一个参数且参数名为value的话,可以将参数名去掉
@RequestMapping(value={"/test", "/user/hello"})
多个URL路径可以映射到同一个处理器的功能处理方法。
2)URI模板模式映射
@RequestMapping(value="/users/{userId}")
{XXX}占位符, 请求的URL可以是"/users/123456"或"/users/abcd",之后可以通过@PathVariable可以提取URI模板模式中的{XXX}中的值
@RequestMapping(value="/users/{userId}/create")
这样也是可以的,请求的URL可以是"/users/123/create"
@RequestMapping(value="/users/{userId}/topics/{topicId}")
这样也是可以的,请求的URL可以是"/users/123/topics/123"
3)Ant风格的URL路径映射
@RequestMapping(value="/users/**")
可以匹配"/users/abc/abc",但"/users/123"将会被【URI模板模式映射中的"/users/{userId}"模式优先映射到】
@RequestMapping(value="/product/?")
可匹配"/product/1"或"/product/a",但不匹配"/product"或"/product/aa";
?代表有且只有一个字符
@RequestMapping(value="/product*")
可匹配"/productabc"或"/product",但不匹配"/productabc/abc";
*代表0~n个字符
@RequestMapping(value="/product/*")
可匹配"/product/abc",但不匹配"/productabc";
@RequestMapping(value="/products/**/{productId}")
可匹配"/products/abc/abc/123"或"/products/123",也就是Ant风格和URI模板变量风格可混用;
**代表所有的子路径
4)正则表达式风格的URL路径映射
从Spring3.0 开始支持正则表达式风格的URL路径映射,格式为{变量名:正则表达式},之后通过@PathVariable可以提取{XXX:正则表达式匹配的值}中的XXX这个变量的值。
@RequestMapping(value="/products/{categoryCode:\\d+}-{pageNumber:\\d+}")
可以匹配"/products/123-1",但不能匹配"/products/abc-1",这样可以设计更加严格的规则。
@RequestMapping(value="/user/{userId:^\\d{4}-[a-z]{2}$}")
可以匹配"/user/1234-ab"
注意:\d表示数字,但是\在java的字符串中是特殊字符,所以需要再加一个\进行转义即可
(参照之前js的学习文档,和java的正则几乎一致,js正则中的一个/变为java中的俩个/即可)
括号:
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。
(red|blue|green) 查找任何指定的选项。
元字符:
. 查找单个任意字符,除了换行和行结束符.如果要表示.这个字符,需要转义
\w 查找单词字符。 字母 数字 _
\W 查找非单词字符。非 字母 数字 _
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
量词:
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 到 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。
11.@ResponseBody注解
该注解用于将处理器中功能处理方法返回的对象,经过转换为指定格式后,写入到Response对象的body数据区(响应正文).一般返回的数据不是html标签的页面,而是其他某种格式的数据时使用,例如给ajax请求返回json数据.
12.SSM框架的搭建
注意:
1.SpringMVC和Spring
不需要什么特殊的配置就可以结合
2.MyBatis和Spring(spring-dao.xml文件)
1)需要引入额外的jar包:mybatis-spring-1.2.2.jar
2)配置数据源
3)把MyBatis中的SqlSessionFactory配置给Spring管理
4)在spring中配置需要扫描的MyBatis映射接口所在包的位置
3.Spring中配置SqlSessionFactory(spring-dao.xml文件)
1)可以在MyBatis的mybatis-config.xml中把MyBatis的信息配好,然后再让spring读取这个mybatis-config.xml文件
2)可以删除mybatis-config.xml文件,然后MyBatis的信息都配置到Spring中
4.spring配置文件中的重要信息(spring-dao.xml文件)
可以写在外部的资源文件中,然后再使用spring的标签读出来使用
例如:
<context:property-placeholder location="classpath:db.properties"/>
取值使用的形式:${key}
${driverClassName}
5.事务配置(spring-service.xml文件)
1)事务的开启和提交需要配置在service层方法的俩端
2)配置事务需要三步
配置事务管理器
使用jdbc的事务管理器
配置事务拦截器
使用tx前缀的标签
spring的aop配置(把事务管理织入到指定的切入点)
使用aop前缀的标签
6.日志配置(log4j.properties文件)
1)使用之前MyBatis的日志文件即可
2)在log4j.properties文件中可以屏蔽掉spring日志(输出太多了...)
#ALL DEBUG INFO WARM ERROR FATAL OFF
log4j.logger.org.springframework = ERROR
7.web.xml文件配置
1)配置spring读取的配置文件
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring_dao.xml
classpath:spring_service.xml
</param-value>
</context-param>
2)配置编码过滤
3)配置前端控制器
8.SpringMVC的容器和Spring容器的关系
1)使用xml或者注解进行配置,springMVC或者spring读取配置信息之后,会把配置的对象(就是spring中的bean)放到容器中进行管理
2)服务器启动的时候,SpirngMVC中的前端控制器会读取配置文件,把相关配置的对象放到自己产生的容器中进行管理(需要在web.xml配置)
3)服务器启动的时候spring也会读取配置文件,把相关配置的对象放到自己产生的容器中进行管理(需要在web.xml配置)
4)SpirngMVC创建容器中所管理的Bean一般是只对SpringMVC有效,如Controller、HandlerMapping、HandlerAdapter等等(因为它一般只读取SpringMVC的配置文件)
5)Spirng创建容器中所管理的Bean一般是对于整个应用程序共享的,一般如DAO层、Service层Bean。(因为它一般只读取service层和dao层的配置文件)
6)SpirngMVC创建的容器 【继承了】 Spirng创建的容器
7)子容器可以从父容器中拿出bean来使用,但是父容器不能从子容器中拿bean来使用。所以在Controller中可以注入service层的实现类对象,Controller在SpringMVC创建的容器中,service是在Spring创建的容器中。