SpringMVC(一)

1spring MVC介绍以及架构原理
1.1sprig MVC介绍
1.1.1什么是MVC
MVC的全名Model View Controller,即模型-视图-控制器的缩写,这是一种设计模式,而非架构。MVC它强制的使用应用程序的输入、处理、和输出分开,这三个核心组件分别处理各自的的任务,最典型的MVC模式就是:jsp+servlet+javabean的模式
用户的请求通过servlet(controller、service、dao)处理后,通过将数据库的信息映射成对应的javabean,并将该数据在页面显示(view),这就是一个最基本的MVC的模式。
这种设计模式的好处:降低的各模块之间的耦合性(如果视图层需要改变其代码,修改页面样式,就不涉及到controller和model层代码;如果需要修改业务逻辑,这个时候是不需要修改与其相关的view视图代码等);重用性高:多个视图可以共享一个数据模型,比如pc端下单和移动端下单,虽然订购的方式不一样,但是处理该数据的方式都是一样的;可维护性高等优点。
1.1.2spring MVC
springMVC实现了基于MVC设计模式的一个MVC框架,而且与spring无需整合,其本身就与spring框架集成。
1.2spring MVC架构原理
1.2.1MVC处理请求流程
在这里插入图片描述
1.2.2spring MVC架构原理
在这里插入图片描述
springMVC请求流程:
1、用户发送请求,通过前端控制器DispatcherServlet处理我们请求的url,在启动前端控制器时,我们需要加载-servlet.xml的配置文件。
2、如何处理我们的url呢?通过处理器映射器HandlerMapping处理请求的url,并返回一个HandlerExecutionChain对象,该对象中包含了interceptor、handler信息。
3、通过处理器映射器返回的Handler,我们将该Handler通过处理器适配器HandlerAdapter适配并找到我们对应的自定义的Handler(Controller)并处理对应的方法,在处理后并返回一个ModelAndView对象,该对象包含了我们的视图信息和数据信息
4、前端控制器获取到MV对象后,通过视图解析器ViewResolver解析我们的MV,将数据Model信息渲染(添加) 到我们的视图View(jsp、vilocity等)上
5、最后由前端控制器返回我们的响应信息。
2环境搭建
我们这里选用的spring的版本号为spring3.1.x
2.1jar包
我们选择我们需要的jar包。需要明白各个包的含义。
在这里插入图片描述

在运行后还需commons-logging包。
在这里插入图片描述
2.2前端控制器配置
在这里插入图片描述
2.3异常
异常信息:文件找不到
在这里插入图片描述
提示我们的文件找不到,我们通过原理图看到,在我们启动我们的前端控制器时我们需要加载-servlet.xml文件。或者我们可以通过看源码信息。
在这里插入图片描述
根据源代码,我们在WEB-INF下添加servlet文件。
2.4添加-servlet.xml
注意添加头信息的来源,我们从project中将我们的头信息拿过来。将该文件添加到我们的WEB-INF下,并发布项目,正常运行。
在这里插入图片描述
2.5修改-servlet.xml文件名称
继续看源码,并从中获取答案。
在这里插入图片描述
2.6修改该配置文件的位置
源码信息,我们可以配置init-param修改加载所需文件的位置。
在这里插入图片描述
修改位置:
在这里插入图片描述
2.7启动并访问主页
在这里插入图片描述
到这里,我们springmvc环境搭建成功!这里更多的是需要我们关注源码信息并掌握如何去学习一门新的技术框架。这里是springmvc,所以我们大概能知道哪些是我们需要的jar包,哪些不是,如果在学一门我们不熟悉的框架时,我们可以将其jar包全部导入。
3入门程序
3.1需求
查询全部的商品信息,这里我们先使用静态数据。
3.2非注解实现Controller
3.2.1配置访问方式一
3.2.1.1编写Controller,实现Controller接口
在这里插入图片描述
3.2.1.2配置处理器映射器
HandlerMapping下的接口,我们先使用BeanNameUrlHandlerMapping配置处理器映射器,该处理器映射器时根据Controller的名称来访问对应的Handler。
源码信息如下:
在这里插入图片描述
在这里插入图片描述

配置信息如下:
在这里插入图片描述
3.2.1.3处理器适配器的配置
在这里插入图片描述

这了我们使用SimpleControllerHandlerAdapter配置我们的处理器适配器。这也是为什么我们自定义的Controller为什么要实现Controller接口的原因。
在这里插入图片描述

配置信息:
在这里插入图片描述
3.2.1.4视图解析器的配置
在这里插入图片描述

配置信息:
在这里插入图片描述
3.2.1.5配置自己的Controller
配置自己的Controller,通过BeanName访问。
在这里插入图片描述
3.2.1.6访问地址
地址:http://localhost:8080/springmvc1109/oneController.action
3.2.2配置访问方式二
3.2.2.1处理器映射器配置
第一种我们是通过BeanNameUrlHandlerMapping配置我们的处理器映射器,这里我们通过SimpleURLHandlerMapping配置访问我们的Handler。
在这里插入图片描述

配置信息:与BeanNameUrlHandlerMapping互不产生影响
在这里插入图片描述
3.2.2.2访问地址
地址:http://localhost:8080/springmvc1109/propOneController.action 或者
http://localhost:8080/springmvc1109/entryOneController.action

3.2.3配置访问方式三

我们都知道在配置处理器适配器时,我们看到代码判断我们的Controller的类型,那么我们通过配置HttpRequestHandlerAdapter处理器适配器,这时,我们需要定义的Controller需要实现HttpRequestHandler接口
在这里插入图片描述
3.2.3.1编写Controller
在这里插入图片描述
3.2.3.2配置处理器适配器
在这里插入图片描述
3.2.3.3配置自己的Controller
在这里插入图片描述
3.2.3.4访问地址
通过BeanName访问。
地址:http://localhost:8080/springmvc1109/twoController.action
3.2.4总结
3.2.4.1默认配置
在这里,springmvc在启动时,处理器映射器、处理器适配器、视图解析器都默认给配置了,因此在上面的配置信息中,我们不需要配置。我们打开xxx.web.servlet.xxxjar包信息,并打开DispatcherServlet.properties文件。如果我们使用默认的配置,那么我们需要将自己已配置的信息关闭。比如,我们关闭BeanNameUrlHandlerMapping配置,那么想使用默认配置的处理器映射器,我们也要把SimpleURLHandlerMapping配置信息关闭。否则用已配置的。
在这里插入图片描述
3.2.4.2实现Controller的两种方式
上面的不管是通过哪种方式配置我们的处理器映射器还是处理器适配器,我们的Controller只能实现Controller接口或者HttpRequestHandler接口,而且只需要实现其中的方法即可,但是在实际开发中,我们一个Controller代表一个模块,我们希望该Controller中有多个方法,那怎么办?如果我们不实现这两个接口中任何一个呢?
其实我们知道实现这两个接口只是表明我是一个Handler而已,并通过处理器适配器匹配(匹配到该Controller是哪种类型就通过哪个适配器去处理)。那既然这样,我们能不能通过注解的方式表明我就是一个Controller呢?
3.3注解的方式实现Controller
3.3.1编写自己的Controller
在这里插入图片描述
@Controller:申明该类是一个Controller
@RequestMapping:配置访问的URL,可以不写.action
3.3.2配置映射器和适配器
这里我们需要配置注解的处理器映射器和处理器适配器。我们知道DispatcherServlet.properties默认加载了基于注解的配置信息,但是默认的配置信息是基于spring3.0.x版本的,在spring3.0.x版本以后,即spring3.1.x我们使用另外两个注解类来配置我们的处理器映射器和处理器适配器。
3.3.2.1基于注解的处理器映射器配置
在这里插入图片描述
3.3.2.2基于注解的处理器适配器配置
在这里插入图片描述
3.3.2.3实际开发
在实际开发中,我们使用注解驱动的方式代替上面两种配置,使用这种配置默认加载了很多我们需要的类型转换器,如json,我们还可以自定义自己的类型转换器添加到该配置中。
在这里插入图片描述
3.3.3配置Controller
这里我们不再单个配置我们的Controller,我们通过批量扫描的方式将带有@Controller、@Service、@Repository注解的类进行扫描,并通过spring bean容器来维护
在这里插入图片描述
3.3.4访问地址
地址:http://localhost:8080/springmvc1109/queryItems.action
3.3.5更改视图解析器配置
我们的视图信息都直接写在我们的代码中,是非常不方便维护的,我们看看源码中视图信息是否还有其他的配置信息,InternalResourceViewResolver。
在这里插入图片描述
我们可以配置逻辑视图地址,在通过视图解析器解析后,加上前缀和后缀信息,拼接成一个物理视图地址,这样不仅方便开发,也利于维护我们的视图地址。
3.3.5.1视图解析器配置
在这里插入图片描述
3.3.5.2修改Controller
在这里插入图片描述
启动并访问,没有问题。
3.3.6其他配置
3.3.6.1窄化请求
用于分类化管理Controller
在这里插入图片描述
访问地址:http://localhost:8080/springmvc_mybatis1109/items/queryItems.action
3.3.6.2限定http请求的方法类型
在这里插入图片描述
这里我们设置的是POST请求,因此报错。
在这里插入图片描述
3.4springmvc源码解读
思想:既然要看源码,我们要学会如何查看源码,即找到重点的类和方法,这里我们都知道springmvc的前端控制器时一个servlet,既然是一个servlet我们需要看什么方法?(servlet中,不管是get请求还是post请求,首先都要走service方法,那么我们是否看看该DispatcherServlet中是否有service方法呢?同学们是这样考虑的么?),我们发现该类中有一个doService方法,所以我们根据此方法解读下去。
1、找到doService方法
该方法调用doDispatcher方法
2、doDispatcher方法中重要方法说明
在这里插入图片描述
在这里插入图片描述
3、进入render方法(解析mv对象)
在这里插入图片描述
4、进入render方法(将model渲染到指定的视图上)
在这里插入图片描述
进入该类的方法中,我们在视图解析器中是配置了InternalResourceViewResolver。
在这里插入图片描述
在这里插入图片描述
5、exposeModelAsRequestAttributes方法
将数据设置到request中。
在这里插入图片描述
6、最后的信息
将请求转发。
在这里插入图片描述

源码总结:通过源码得出,实际上内部就是通过request设置数据和将页面转发。
4springmvc与mybatis的整合
4.1整合思路
所谓的整合思路,就是这两个框架发挥各自特长,我们知道springmvc可以做前端控制器Controller,而且还可以管理事务、IOC、DI、AOP;mybatis的是一个持久层框架,开发dao。
在这里插入图片描述
4.2所需jar包
4.2.1分析:(必须要分析)
与spring无缝整合:spring的相关包,如:aop、bean、context、exception、orm等
与mybatis整合:mybatis-spring的整合包、log4j、mybatis的相关包
操作数据库:数据库驱动包、数据库连接池的包

以及上面所需包的依赖包。这里我已将整合需要的包整理好。
在这里插入图片描述
4.2.2分目录存放我们的配置文件
在这里插入图片描述
4.3需求
查询商品的列表信息,不使用静态数据。
4.4整合dao层
4.4.1思路
dao层为持久层,即与mybatis整合。既然与mybatis整合,我们需要通过spring管理哪些?
1、数据源管理
2、SqlSessionFactory管理
3、mapper接口的代理对象的管理(批量)
4、还需要的文件:db.properties、log4j.properties、SqlMapConfig.xml全局配置文件
4.4.2添加基本文件信息
在这里插入图片描述
4.4.3编写applicationContext-dao.xml文件
将spring相关文件放置到spring文件夹中同一管理。
在这里插入图片描述
4.4.4使用逆向工程生成的mapper接口和映射文件
在这里插入图片描述
4.4.5添加两个pojo对象
4.4.5.1ItemsCustom
在实际开发时,我们可能会根据需求的变更修改我们的表信息,既然修改表信息,我们就需要修改对应的pojo,因此我们可以扩展我们的pojo,在修改表后,我们通过逆向工程重新生成pojo,而我们扩展的pojo不会受影响。添加业务属性时如flag,判断该商品是否过期。
在这里插入图片描述
4.4.5.2ItemsQueryVo
包装类型的pojo,使用该对象作为查询条件,我们可以包装很多的查询信息,这个在将mybatis框架时已讲过,这里不再复述。
在这里插入图片描述

4.4.6接口和映射文件的编写
4.4.6.1接口定义
在这里插入图片描述
4.4.6.2映射文件编写
在这里插入图片描述
4.5整合service
这里我们通过getBean的方式获取对象
4.5.1接口定义
在这里插入图片描述
4.5.2实现类
在这里插入图片描述
4.5.3spring管理service的bean
编写applicationContext-service.xml
在这里插入图片描述
4.5.4sprig管理实务
配置spring个实务管理:applicationContext-transaction.xml
在这里插入图片描述
4.6与spring整合
与spring无需整合
4.6.1配置spring前端控制器加载所需文件
在这里插入图片描述
4.6.2加载所有的文件信息
我们可以通过在springmvc.xml文件中去包含需要加载的文件信息,但是这里我们直接在web.xml中通过监听加载我们的配置文件信息。
在这里插入图片描述
4.7测试
4.7.1编写Controller
在这里插入图片描述
4.7.2访问地址
地址:http://localhost:8080/springmvc_mybatis1109/queryItems.action
在这里插入图片描述
5Controller返回值
5.1需求
修改商品信息
先根据id查询商品信息-在form表单显示-最后保存
5.2接口中定义方法
首先我们需要在dao中定义根据id查询商品信息的方法,但是我们的生成的代码中已有,所以我们只需要在service中定义根据id查询商品信息的方法,然后在调用已有接口中的方法即可
5.2.1service接口方法定义
这里需要注意我们接口中定义方法的参数的类型,这里我们定义为包装类型,方便用于业务逻辑的判断。
在这里插入图片描述
5.2.2service实现类
这里需要将items值赋值到ItemsCustom中。
在这里插入图片描述
5.3Controller方法定义
5.3.1返回ModelAndView
返回ModelAndView这里就不演示了,参照第一个案例
5.3.2返回String
5.3.2.1返回视图的逻辑地址
在这里插入图片描述
5.3.2.2redirect
保存商品信息后,重定向到list页面。需要注意的是,redirect会将request重新创建,而且不会共享数据。
在这里插入图片描述
那如何判断request是否重新创建呢?我们在方法中定义request变量。
5.3.2.3forward
保存商品信息后,重定向到list页面。需要注意的是,forward不会重新创建request,而且会共享数据。
在这里插入图片描述
5.3.3返回void
在controller方法形参上可以定义request和response,使用request或response指定响应结果:
1、使用request转向页面,如下:
request.getRequestDispatcher(“页面路径”).forward(request, response);

2、也可以通过response页面重定向:
response.sendRedirect(“url”)

3、也可以通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding(“utf-8”);
response.setContentType(“application/json;charset=utf-8”);
response.getWriter().write(“json串”);
6springmvc参数绑定
6.1什么是参数绑定
springmvc的参数绑定就是将请求的key/value数据,通过springmvc参数绑定的特性将其绑定到对应Controller方法的形参上,该过程主要是通过HandlerMethodArgumentResolver类处理。在参数绑定的过程中,如果请求的key/value与绑定到形参数据类型不一致,我们可以通过类型转换器来处理,即Converter实现。
6.2默认支持的参数绑定
例如:如果需要request、response、model这些对象时,我们可以直接在方法的形参中添加这些变量。
6.2.1HttpServletRequest
通过request对象获取请求信息
6.2.2HttpServletResponse
通过response处理响应信息
6.2.3HttpSession
通过session对象得到session中存放的对象
6.2.4Model/ModelMap
model是一个接口,modelMap是一个接口实现 。
作用:将model数据填充到request域。
6.3简单类型的参数绑定
完善需求:在修改商品时,我们是根据id查询对应的商品信息,那里的id硬编码了,我们应该动态获取id值。
在这里插入图片描述
6.3.1请求的key与形参中的变量名一致
我们在修改时,url中拼接了参数信息,因此我们只需要将该参数名添加到我们的方法的形参上面即可。
在这里插入图片描述
在这里插入图片描述
这样便将id绑定到方法的形参中。
6.3.2请求的key与形参中的名称不一致
如果请求的key与形参中的变量名称不一致,我们可以通过@RequestParam注解实现,该注解中填写的value应与key一致即可。
在这里插入图片描述
@RequestParam中还有一个defaultValue属性,可以设置默认值。
6.4pojo的参数绑定
完善需求:在保存商品信息的时候我们是没有保存数据的,因为我们需要将修改后的对象信息拿到,因此这里我们需要接收pojo类型的参数。同上面一样,我们需要在方法的形参上添加我们的pojo类型,即ItemsCustom。形参中添加该pojo的前提条件是,该对象的属性名与jsp页面表单中的name属性名必须一致,否则完成不了绑定。
经测试,我们的数据能绑定成功,但是出现中文乱码。
6.4.1解决中文乱码
要知道为什么出现乱码。
jsp页面为UTF-8,信息经过tomcat容器编码后(ISO-8859-1)出现乱码,因此我们需要转码。
我们可以通过这种方式处理我们的乱码问题:
String name = new String(itemsCustom.getName().getBytes(“ISO-8859-1”), “UTF-8”);
但是在实际开发过程中,我们不会这么中,统一通过过滤器处理。因此我们需要在过滤器中配置处理乱码。
在这里插入图片描述
6.4.2时间转换器
我们刚解决了乱码问题,发现我们的时间不能转换,因此我们需要自定义类型转换器。这里我们在自定义的时间类型转换器的过中,我们的格式为”yyyy-MM-dd HH:mm:ss”,可能有人会说其他格式,但是在开发中我们的都是通过插件选择时间。
6.4.2.1自定义时间转换器
实现converter接口。
在这里插入图片描述
6.4.2.2加载自定义的类型转换器
spring加载自定的参数绑定。
在这里插入图片描述
在这里插入图片描述
到这里我们就可以将我们的pojo完成了参数绑定的过程。
6.4.3完成更新操作
6.4.3.1service接口定义方法
在这里插入图片描述
6.4.3.2service实现
在这里插入图片描述
6.4.3.3完善Controller
在这里插入图片描述
7springmvc与Struts2区别
7.1使用上
DispatcherServlet—StrutsPrepareAndExecuteFilter
Handler(实现Controller或者HttpRequestHandler)—Action(实现ActionSupport)
HandlerInterceptor—Interceptor,由于sping是面向切面的编程,因此拦截器在spring中被弱化
HandlerMethodArgumentResolver-Model,spring通过参数绑定,而Struts2通过模型驱动或者属性驱动获取数据
ViewResolver解析—通过配置result指定一个具体的页面
7.2本质上
1、springMVC基于方法的开发,我们可以通过我们的代码中,我们没有所谓的数据域对象,除了引用的service就只有方法,而Struts2是基于类的开发,该类中有各种各样的全局变量,因此我们说Struts2基于类的开发。
2、springMVC可以单例开发,并且建议单例开发,因为springMVC通过controller的形参接收数据,方法结束后形参数据销毁;而Struts2则是通过模型驱动或者属性驱动获取数据,而且这些变量都是全局变量,因此Struts2是多例开发。
3、经常会说Struts2框架性能不好,是由于使用了Struts2的标签,从而加载很多的服务导致所谓的框架慢,所以我们建议使用页面使用jstl
4、所谓框架的性能,是与提供的服务的多少有关,而不是根据包的大小有关。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值