spring-mvc

来源:互联网 发布:mac上前端开发软件 编辑:程序博客网 时间:2024/06/05 17:09
一.springmvc框架
1.什么是springmvc
springmvc是spring 框架的一个模块,springmvc和spring无需通过中介整合层整合。
springmvc是一个基于mvc的web 框架

2.mvc在b/s系统下的应用
mvc是一个设计模式,应用流程:浏览器发出请求到Controller控制器,控制器请求Moder(模型控制器)进行处理,得到Model返回的结果并将其发送至

View视图控制器(将模型数据添加到request域)

3.spring mvc框架执行流程

①浏览器发出请求到前端控制器(DispatcherServlet,接受用户请求并响应)
②DispathcerServlet向 HanderMapping(处理器映射器,根据请求找到对应的处理器)请求查找Handler(处理器也称为controller,根据xml或注解查找)
③HandlerMapping返回一个执行链(HandlerExctionChain,其中包括了一个Handler,其中也可以有多个拦截器)
④DispatcherServlet调用处理器适配器(HandlerAdapter)去执行返回的Handler
⑤HandlerAdapter返回ModelAndView(是springmvc的底层对象,包括了Model 和 View)
⑥DispathcerServlet请求视图解析器(View Resolver) 进行视图解析,根据逻辑视图名解析成真正的视图(jsp)
⑦ViewResolver 返回一个view,DispatcherServlet进行视图渲染,将模型数据(在moderlandview中)填充到request域
⑧DispathcerServlet响应浏览器

涉及的重要组件:
前端控制器(DispathcerServlet):接受请求,响应结果,相当于转发器,中央处理器,有了它的存在减少了其它组件之间的耦合性,不需要程序猿开发
处理映射器(HandlerMapping):根据请求的url查找 handler,不需要程序猿开发
处理器适配器(HandlerAdapter):按照特定的规则执行handler 需要程序猿开发
注意:编写handler时按照HandlerAdapter的要求去做,这样适配器才可以正确执行handler
处理器(handler):对请求进行处理,需要程序猿编写
视图解析器 (ViewResolver):进行逻辑视图解析成真正的视图(view)不需要程序猿开发

视图(View):是一个接口,能够支持不同的View类型(jsp,freemarker..),需要程序猿开发jsp

二.spring-mvc入门程序
需求:查询所有商品 
1.配置前端控制器(在web.xml中)

<!--springmvc 前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- contextConfigLocation而配置springmvc加载的配置文件(配置处理器映射器,处理器适配器等)--><!-- 如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml)--><init-param><param-name>contextConfigLocation</param-name><param-valule>Classpath:springmvc.xml</param-valued></intit-param></servelt><servlet-mapping><servlet-name>springmvc</servlet-name><!--servlet匹配方式:第一种:*.action 访问以.action结尾的servlet,由DispatcherServlet进行解析第二种:/ 所有的访问地址都由DispatcherServlet进行解析,对于静态文件需要配置不让DispatcherServlet解析,使用此方式可以实现RESTful风格的url第三种:/* 这样配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet解析jsp地址,不能跟根据jsp找handler会报错。 --><url-pattern>*.action</url-pattern></servlet-mapping>
项目下新建文件springmvc.xml

2.在springmvc.xml中配置处理器映射器,适配器,视图解析器(顺序无所谓)
①配置处理器适配器
查看源代码中的supports方法可以知道适配器支持哪一种Handler(这里是执行实现Controller 接口)

<!-- 处理器适配器 所有的处理器适配器都实现HandlerAdapter接口 --><bean  class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdatpter"/>

②编写并配置 handler(需要实现Controller接口,才能由上面指定的适配器执行)
public class ItemsController1 implements Controller{@Overridepublic ModerAndView handlerRequest(HttpServletRequest rq,HttpServletResponse rs) throws Exception{//调用service查找数据库,这里使用静态数据模拟List<Items> itemsList = new ArrayList<Items>();//向List中填充静态数据........//返回ModelAndViewModelAndView mdv = new ModelAndView();//相当request.setAttribute(key,value),在jsp页面中通过itemsList 获取数据mdv.addObject("itemsList",itemsList);//指定视图mdv.setViewName("/WEB-INF/jsp/items/itemsList.jsp");return mdv;}}
将所写的handler 配置到运行环境中

<!--配置handler --><bean name="/queryItems.action" calss="cn.ssm.controller.ItemsController1"/>
③配置映射器

<!--将bean 的name当做url 进行查找,需要在配置handler 时指定name(url) --><bean  class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
④编写视图 itemsList.jsp,在其中接收ModerlAndView传过来的数据
⑤配置视图解析器

<!-- 视图解析器,解析jsp 默认使用jstl 标签,classpath下得有 jstl 的包--><bean  class="org.springframework.web.view.InternalResourceViewResolver"/>

3.非注解方式配置处理器映射器,适配器
3.1非注解映射器
SimpleUrlHandlerMapping是BeanNameUrlHandelrMapping的增强版本,它可以将url 和处理器的bean的 id 进行统一配置

<!--配置handler --><bean id="itemsController1" calss="cn.ssm.controller.ItemsController1"/><!- 简单URL 映射--><bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><!--对ItemsController1进行映射,url是/queryItems1.action --><prop key="/queryItems1.action">itemsController1</prop><prop key="/queryItems2.action">itemsController1</prop></props></property></bean>
总结:多个映射器可以并存,前端控制器判断URL能让哪个映射器处理就让对应的映射器处理
3.2非注解适配器
①org.springframework.web.servlet.mvc.SimpleControllerHandlerAdatpter,这个适配器要求编写的handler实现controller接口

②org.springframeword.web.servlet.mvc.HttpRequestHandlerAdatpter,http请求处理器,所有实现了org.springframework.web.HttpRequestHandler 接口
的Bean通过此适配器进行适配执行。
适配器配置如下:

<!-- 另一个非注解的适配器--><bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdatpter">
controller实现如下:
public class ItemsController2 implements HttpRequestHandler{@Overriderpublic ModerAndView handlerRequest(HttpServletRequest rq,HttpServletResponse rs) throws Exception{//调用service查找数据库,这里使用静态数据模拟List<Items> itemsList = new ArrayList<Items>();//向List中填充静态数据........//设置模型数据request.setAttribute("itemsList",itemsList);//设置转发的视图request.getRequestDispathcer("/WEB-INF/jsp/items/itemsList.jsp").forward(request,response);}}

配置刚写的handler
<!--配置handler --><bean id="itemsController2" calss="cn.ssm.controller.ItemsController2"/><!- 简单URL 映射--><bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><!--对ItemsController1进行映射,url是/queryItems1.action --><prop key="/queryItems1.action">itemsController1</prop><prop key="/queryItems2.action">itemsController1</prop><prop key="/queryItems3.action">itemsController2</prop></props></property></bean>
总结:使用此方法可以修改response,设置响应的数据格式,比如响应json数据
4.注解方式配置处理器映射器,适配器

<!-- 注解映射器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>注解描述:@RequestMapping :请求url到处理器功能方法的映射<!-- 注解适配器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/><!--使用mvc 注解驱动,可以代替上面映射器和适配器的配置,该mvc 注解驱动默认加载很多参数绑定方法,比如json的转换解析器就默认加载了,实际开发用这种方式 --><mvc:annotation-driven></mvc:annotation-driven>
5.注解方式开发handler
使用注解的映射器和注解的适配器(二者必须配对使用)
//使用Controller标识它是一个控制器@Controllerpublic class ItemsController3{//商品查询列表//建议url和方法名一样@RequesMapping("/queryItems")//该注解对queryItems方法和url进行映射,一个方法对应一urlpublic ModerAndView queryItems() throws Exception{//调用service查找数据库,这里使用静态数据模拟List<Items> itemsList = new ArrayList<Items>();//向List中填充静态数据........//返回ModelAndViewModelAndView mdv = new ModelAndView();//相当request.setAttribute(key,value),在jsp页面中通过itemsList 获取数据mdv.addObject("itemsList",itemsList);//指定视图mdv.setViewName("/WEB-INF/jsp/items/itemsList.jsp");return mdv;}//在这里还可以定义其它方法,比如商品添加修改功能}
写完后需要spring容器中加载该handler
<!--对于注解的handler可以进行单个配置 --><bean  calss="cn.ssm.controller.ItemsController2"/><!--实际开发中建议使用组件扫描,可以扫描controller,service...这里让组件扫描controller,指定controller的包 --><context:component-scan base-package="cn.ssm.controller"></context:component-scan>
6.配置视图解析器
<!-- ViewResolver--><bean class="org.springframework.web.servlet.view.internalResourceViewResolver"><property name="prefix" vlaue="/WEB-INF/JSP"/><property name="suffix" vlaue=".jsp"/></bean>

配置视图解析器后,上面返回视图的路径修改为:mdv.setViewName("items/itemsList");

三.springmvc与mybatis的整合
spring的作用:将各层进行整合,通过spring管理持久层的mapper(相当于dao接口),管理业务层的Service,service中可以调用mapper接口,管理表现层的handler,handler中可以调用service方法
mapper,service,handler都是javabean

需求;使用springmvc 和 mybatis 完成商品列表的查询

1.整合思路:
第一步:整合持久层(dao层)
mybatis与spring 的整合,通过spring 管理mapper接口,使用spring扫描器自动扫描mapper接口在spring中进行注册
第二步:整合servie 层
通过spring 管理service接口,使用配置的方式将service 接口配置在spring配置文件中,实现事务控制
第三步:整合springmvc
由于springmvc是 spring的模块,不需要整合
2.环境搭建
需要的jar包:
数据库驱动包 mysql 5.5
mybatis 的包
mybatis 和spring 的整合包
日志log4j包
dbcp数据库连接池
spring 的包
jstl包

3.整合dao


3.1 SqlMapConfig.xml(mybatis目录下)

<全局setting配置,根据需要再加
<settings></settings><!-- 配置mapper由于我们使用spring 和 mybatis 的整合包进行mapper扫描,所以这里不需要配置必须遵循的规则:mapper.xml 和 mapper.java 同名且在一个目录--><!-- 配置别名--><typeAliases><!-- 批量扫描别名--><package name="in.ssm.po"/></typeAliases>

3.2 applicationContext-dao.xml(spring目录下)
配置数据源,SqlSessionFactory,mapper扫描器

<!--加载数据库配置文件 --><context:property-placeholder location="classpath:db.properties"/><!--数据源,使用dbcp --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSouce" destroy-methos="close"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="maxActive" value="10"/><property name="maxIdle" value="5"/></bean><!-- 配置sqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 加载myabtis的配置文件--><property name="configLocation" value="mybatis/SqlMapConfig.xml"/><!--数据源 --><property name="dataSource" ref="dataSource"/></bean><!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器转中注册--><!--遵循规范:将mapper接口类名和mapper.xml映射文件保持一致,且在一个目录中 --><!--自动扫描出来的mapper的bean的 id 为 mapper类名(首字母小写) --><bean clss="org.mybatis.spring.mapper.MapperScannerConfigure"><!-- 指定扫描的包名,用此种方式则SqlMappConfig.xml就无需配置对mapper.xml的扫描如果扫描多个包,每个包之间使用半角逗号分隔--><property name="basePackage" vlaue="cn.mybatis.mapper"><property name="sqlSessionFactorBeanName" value="sqlSessionFactory"/></bean>

3.3逆向工程生成po 类以及单表的增删改查
3.4 手动定义商品查询的mapper
针对综合查询mapper 一般会有关联查询,建议自定义mapper
在mapper 目录下新建 ItemsMapperCustom.xml 和 ItemsMpperCustom.java(接口)

①ItemsMapperCustom.xml
sql 语句: select * from items where items.name like '%笔记本%'
<!--商品列表查询 --><!-- parameterTyep建议传入包装对象(包装了查询条件),定义类ItemsQueryVoresultType:使用扩展对象--><select i="findItemsList" parameterType="cn.ssm.po.ItemsQueryVo" resultType="cn.ssm.po.ItemsCustom">select * from items <where><include refid="query_items_where"/></where></select><!-- 定义商品查询的Sql 片段,商品的查询条件--><sql id="query_items_where"><!-- 使用动态sql,通过if判断,满足条件进行sql 拼接--><!-- 商品查询条件通过ItemsQueryVo中的属性ItemsCustom进行传递--><if test="itemsCustom!=null"> <if test="itemsCustom.name!=null and itemsCustom.name!=' '">items.name like '%${itemsCustom.name}%'</if></if></sql>

public calss ItemsQueryVo{//商品的包装对象//商品信息private Items items;//为了系统的可扩展性,对原始po(这里是Items)进行扩展//商品信息的扩展类private ItemsCustom itemsCustom;/*属性的get(),set()*/}public calss ItemsCustom extends Items{//商品信息的扩展类//添加商品的扩展属性}②ItemsMpperCustom.java(接口)public interface ItemsMpperCustom{//商品查询列表public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;}
4.整合sevice
4.1 让spring 管理service接口
创建 service 接口
public interface ItemsService{
//商品查询列表
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;

}
实现接口
public interface ItemsServiceImpl implements ItemsService{
private ItemsMapperCustom itemsMapperCustom;
@Override
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception{
//通过ItemsMapperCustom 查询数据库
return itemsMapperCustom.findItemsList(itemsQueryVo);

}

}

4.2 配置service
创建 appliactionContext-service.xml

<!-- 商品管理的service--><bean id="itemsService" class="cn.ssm.service.impl.ItemsServiceImpl"/>
4.3 添加事务控制
创建 appliactionContext-transaction.xml
在其中使用声明式进行配置
<!-- 事务管理器,对mybatis操作数据库的事务控制,使用jdbc的事务控制类--><bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 数据源,之前在appliactionContext-dao.xml中进行配置过了,这里直接引用--><property name ="dataSource" value="dataSource"/></bean>
4.4 通知
<tx:advice id="tx:Advice" transaction-manager="transactionManager"><tx:arributes><!-- 传播行为--><tx:method name="save" propagation="REQUIRED" /><tx:method name="delete" propagation="REQUIRED" /><tx:method name="insert" propagation="REQUIRED" /><tx:method name="update" propagation="REQUIRED" /><tx:method name="find" propagation="SUPPORTS" read-only="true"/></tx:arributes></tx:advice><!-- aop--><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.ssm.service.impl.*.*()..)"/></aop:config>
5.整合springmvc
①创建springmvc.xml 配置映射器,适配器,视图解析器
<!--实际开发中建议使用组件扫描,可以扫描controller,service...这里让组件扫描controller,指定controller的包 --><context:component-scan base-package="cn.ssm.controller"></context:component-scan><!--使用mvc 注解驱动,可以代替上面映射器和适配器的配置,该mvc 注解驱动默认加载很多参数绑定方法,比如json的转换解析器就默认加载了,实际开发用这种方式 --><mvc:annotation-driven></mvc:annotation-driven>配置视图解析器<!-- ViewResolver--><bean class="org.springframework.web.servlet.view.internalResourceViewResolver"><property name="prefix" vlaue="/WEB-INF/JSP"/><property name="suffix" vlaue=".jsp"/></bean>②在web.xml中配置前端控制器<!--springmvc 前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- contextConfigLocation而配置springmvc加载的配置文件(配置处理器映射器,处理器适配器等)--><!-- 如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml)--><init-param><param-name>contextConfigLocation</param-name><param-valule>Classpath:springmvc.xml</param-valued></intit-param></servelt><servlet-mapping><servlet-name>springmvc</servlet-name><!--servlet匹配方式:第一种:*.action 访问以.action结尾的servlet,由DispatcherServlet进行解析第二种:/ 所有的访问地址都由DispatcherServlet进行解析,对于静态文件需要配置不让DispatcherServlet解析,使用此方式可以实现RESTful风格的url第三种:/* 这样配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet解析jsp地址,不能跟根据jsp找handler会报错。 --><url-pattern>*.action</url-pattern></servlet-mapping>
6.编写 controller
@Controllerpublic Class Controller{private ItemsService itemsService;//商品查询@RequestMapping("/queryItems")public ModerAndView queryItems() throws Exception{//调用service查找数据库,这里使用静态数据模拟List<ItemsCustom> itemsList = itemsService.findItemsList(null); //返回ModelAndViewModelAndView mdv = new ModelAndView();//相当request.setAttribute(key,value),在jsp页面中通过itemsList 获取数据mdv.addObject("itemsList",itemsList);//指定视图mdv.setViewName("/items/itemsList");return mdv;}}
7.加载spring容器
将mapper,service,controller加载到spring容器
在web.xml中使用通配符方法加载上述配置文件
 <!-- 加载spring容器--><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/classes/spring/applicationContext-*.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>


四.商品修改的功能开发
操作流程:
进入商品列表页面
点击修改进入商品修改页面,页面中显示了商品的详细信息(从数据库中根据商品ID查询得到)
修改完后点击提交


1.开发mapper

方法:根据ID查询商品信息
     更新items表的数据
不用开发了,使用逆向工程生成的代码

2.开发servcie
接口功能:
根据ID查询商品信息
修改商品信息 
创建接口

public interface ItemsService{//根据id 查询商品信息public ItemsCustom findItemsById(Integer id) throws Exception'//修改商品信息public void updateItems(Integer id,ItemdCustom,itemsCustom) throws Exception;}实现接口public interface ItemsServiceImpl implements ItemsService{private ItemsMapper itemsMapper;@Overridepublic ItemsCustom findItemsById(int id) throws Exception{ Items item = itemsMapper.selectByPrimaryKey(id);//中间对业务进行处理//...//返回ItemsCustomItemsCustom itemsCustom = new ItemsCustom()://将item的属性拷贝的itemCustom当中BeanUtils.copyProperties(items,itemsCustom);return itemsCustom;}//更新功能@Overridepublic void updateItems(int id,ItemdCustom,itemsCustom) throws Exception{//添加业务校验,通常在Service对关键参数进行校验//校验id是否为空,如果为空,抛出异常//更新商品信息使用 updateByPrimaryKeyWithBlobs,更新items表中所有字段包括大文本类型字段//要求必须传入iditemsMapper.setId(id);itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom); }}

3.开发controller
方法:
商品信息修改页面显示
商品信息修改提交

@Controllerpublic Class Controller{private ItemsService itemsService;//商品查询@RequestMapping("/queryItems")public ModerAndView queryItems() throws Exception{//调用service查找数据库,这里使用静态数据模拟List<ItemsCustom> itemsList = itemsService.findItemsList(null); //返回ModelAndViewModelAndView mdv = new ModelAndView();//相当request.setAttribute(key,value),在jsp页面中通过itemsList 获取数据mdv.addObject("itemsList",itemsList);//指定视图mdv.setViewName("/items/itemsList");return mdv;}}







原创粉丝点击