1.springmvc解释
springmvc:spring的一个模块
以mvc的设计模式实现model和view分离(数据处理和数据显示的分离)的控制层框架 替代servlet
2.springmvc的四大组件
-
DIspatchorServlet:中央控制器:任务调度
作为前端控制器接受请求、给与响应,统一调度:整个流程控制的中心,控制其它组件执行, 降低组件之间的耦合性,提高每个组件的扩展性。
-
HanderMapping:处理器映射器:指定url和controller之间的对应关系
通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 指定url和controller的对应关系
-
HanderAdaper:处理器适配器: 指定什么样的类可以作为处理器controller和分发任务给controller
通过扩展处理器适配器,支持更多类型的处理器。 接受中央控制器的请求 把请求交给对应的controller 指定可以处理请求的controller的类型
-
ViewResolver: 试图解析器:解析modelandview 获取view
通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。 对modelandview进行解析 得到view结果视图
3.servlet四个弊端
- 无法扩展:servlet必须继承HttpServlet 但java只支持类与类的单继承:这样此servlet类就无法继承其他类 没法再扩展
- 无法单元测试:servlet的service/doget/dopost运行时 必须需要参数request和response 而我们没法实例化这两个对象 所以servlet不能进行单元测试
- 复用性差:servlet的魔板步骤:接受请求 处理数据 访问dao层 设置域属性 选择跳转::无法实现代码的复用
- 功能单一:servlet泛滥:一个servlet只能接受和处理一种请求
4.springmvc的过程描述
- DispatcherServlet中央控制器接受客户端请求,
- 中央控制器拿请求咨询HandlerMapping处理器映射器,获取请求url对应的controller处理器
- 中央控制器把请求交给对应的HandlerAdapter处理器适配器, 处理器适配器把请求交给controller处理器
- controller处理器处理请求后 把结果和数据封装为ModelAndView对象 并提交给处理器适配器
- 处理器适配器把ModelAndView传递给中央控制器
- 中央控制器把ModelAndView交给ViewResolver视图解析器 进行解析 解析后得到view 并提交给中央控制器
- 中央控制器对view进行渲染后 响应给客户
5.springmvc四大组件 创建/配置
5.1 中央控制器:DispatcherServlet
通过contextConfigLocation初始化参数指定springmvc的核心配置文件位置
<!-- 3 配置springmvc的中央控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 通过调用servlet的初始化参数指定springmvc的核心配置文件的位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc_config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
5.2 处理器映射器:HandlerMapping
处理器映射器::指定action/controller与url的对应关系
<!-- 配置处理器映射器 :指定controller与url的对应关系-->
<!-- 1:默认处理器映射器:BeanNameUrlHandlerMapping:::通过bean的name属性来指定url -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 2:处理器映射器:SimpleUrlHandlerMapping:::通过bean的id属性指定url::::可以1对n -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- prop标签的文本是bean的id key是action的url -->
<prop key="/demo02/t10.do">demo02_t1</prop>
<prop key="/demo02/t11.do">demo02_t1</prop>
<prop key="/demo02/t12.do">demo02_t1</prop>
<prop key="/demo01/t10.do">demo01_t1</prop>
</props>
</property>
</bean>
<!-- 通过bean标签创建controiller的bean -->
<!-- bean的name值 是此controller的url -->
<bean class="com.zhiyou100.controller.Demo01Login" name="/demo01/login.do" id="demo01_t1"/>
<bean class="com.zhiyou100.controller.Demo02Test" name="/demo02/t1.do" id="demo02_t1"/>
5.3处理器适配器:HandlerAdaptor
1: 分发任务给controller
2:controller需要实现什么借口
<!-- 配置处理器适配器:分发任务+controller的类型 -->
<!-- 1 默认处理器适配器:SimpleControllerHandlerAdapter::conttoller必须实现接口org.springframework.web.servlet.mvc.Controller -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 2 处理器适配器:HttpRequestHandlerAdapter::conttoller必须实现接口org.springframework.web.HttpRequestHandler -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
<bean class="com.controller.Demo022" name="/demo02/t21.do"/>
<bean class="com.controller.Demo01Login" name="/demo01/login.do" id="demo01_t1"/>
5.4 视图解析器:ViewResolver
对modelandview解析 得到view
<!-- 视图解析器:把modelandview解析为view -->
<!-- 唯一的视图解析器:InternalResourceViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 注意:如果不指定prefix和suffix:::modelandview中存储的url为真实路径 -->
<!-- 注意:如果指定了prefix和suffix:::modelandview中存储的url为逻辑路径 -->
<!-- 真实路径 =prefix值+逻辑路径+suffix值 -->
<!-- -->
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
public class Demo031 implements Controller{
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.setCharacterEncoding("utf-8");
String n=req.getParameter("n");
ModelAndView mav=new ModelAndView();
//ModelAndView::作用两个:1设置request域属性+2设置请求转发的资源的路径
mav.addObject("message11", "Demo031:::n="+n);
//完全等价于
req.setAttribute("message12", "Demo031::::::::n="+n);
//mav.setViewName("/jsp/success.jsp");//视图解析器中没有设置prefix和sufdfix::此时设置的跳转的url必须是真实路径
mav.setViewName("jsp/success");//视图解析器中设置prefix和sufdfix::此时设置的跳转的url必须是逻辑路径
//完全等价于
//req.getRequestDispatcher("/jsp/success.jsp").forward(req, resp);
return mav;
}
}