什么是SpringMVC
SpringMVC其实就是spring框架的一个模块,SpringMVC和spring之间可以无缝整合,SpringMVC也是一个非常优秀的基于MVC的web框架,什么是MVC这里就不多说了,下面来了解一下springmvc的执行流程。
SpringMVC执行流程
如上图所示,这是springmvc的执行流程图:
首先,用户向springmvc发送请求,springmvc的前端控制器拦截到用户的请求
springmvc中的前端控制器请求springmvc的处理器映射器查找Handler(通过xml配置或者注解配置)
处理器映射器返回查找到的Handler给前端控制器
前端控制器拿到Handler,请求处理器适配器去执行Handler
处理器适配器去执行Handler
Handler执行完毕返回ModelAndView
处理器适配器执行完Handler之后返回ModelAndView给前端控制器
前端控制器向ViewResolver(视图解析器)传递ModelAndView,视图解析器解析ModelAndView
视图解析器解析完ModelAndView就返回View
前端控制器进行视图渲染(进行数据填充)
前端控制器获取到渲染后的视图
前端控制器将视图对象返回给用户
入门程序HelloWorld
创建一个maven的web项目,导进去相应的jar包,然后开始配置:
第一步是在web.xml
文件中配置前端控制器:
<!--配置前端控制器-->
<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:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
接着是在resource下创建spring-mvc.xml
文件,这里需要注意的是,如果你在这个文件外面再加一个文件夹的话,在前端控制器里面也要修改,否则会找不到这个文件。
然后在spring-mvc.xml
里面配置:
<!--配置处理器映射器,BeanNameUrlHandlerMapping也是spring默认的处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--配置处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--配置自定义controller-->
<bean id="helloController" name="/hello.do" class="com.ssm.core.controller.HelloController"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
接着是自定义controller:
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mv = new ModelAndView();
mv.addObject("hello", "Hello World");
mv.addObject("message","这是第一个spring-mvc的controller");
mv.setViewName("hello");
return mv;
}
}
最后是测试结果:
出现如上就表示我们已经成功了。
程序解析
我们通过上面的例子去理解一下spring-mvc的执行流程:
用户发送请求(在浏览器中发送请求 http://localhost:8080/hello.do)
在
web.xml
中配置的DispatcherServlet
前端控制器拦截用户的请求前端控制器请求在
spring-mvc.xml
中配置的BeanNameUrlHandlerMapping
处理器映射器根据用户请求的url(即是/hello.do
)去寻找Handler,并返回给前端控制器前端控制器拿到Handler之后去请求在
spring-mvc.xml
中配置的处理器适配器SimpleControllerHandlerAdapter
去执行Handler处理器适配器根据前端控制器传来的Handler去寻找相应的我们定义的Controller去调用方法
我们定义的Controller执行完方法之后给处理器适配器返回
ModelAndView
处理器适配器返回
ModelAndView
给前端控制器前端控制器拿到
ModelAndView
之后传给在spring-mvc.xml
中配置的视图解析器InternalResourceViewResolver
去解析视图解析器解析完成视图之后,返回真正的view给前端控制器
前端控制器拿到view之后进行渲染和返回给用户
如上,就是spring-mvc的执行流程
非注解的处理器映射器和处理器适配器
处理器映射器
springmvc有三个处理器映射器,分别是:SimpleUrlHandlerMaping
、ControllerClassNameHandlerMapping
它们分别对应不同的功能:
BeanNameUrlHandlerMapping:是默认配置的,功能是根据url请求去匹配bean的name属性的url获取Controller,使用在上面的例子中
-
SimpleUrlHandlerMaping:根据请求的url去匹配简单的key,在根据key对应的Controller的id去寻找Controller,例如:
我们请求上面中的hello.do
、test.do
、ss.do
都可以访问到同一个HelloController。 ControllerClassNameHandlerMapping:根据
类名.do
(类名首字母小写)去寻找Controller, 已经废弃,就不做演示了
这些处理器映射器之间都可以共存,我们可以同时定义多个。
处理器适配器
springmvc提供有两个处理器适配器:
- SimpleControllerHandlerAdapter:需要实现Controller接口,调用Controller里面的方法,返回
ModelAndView
,使用如上面的例子 - HttpRequestHandlerAdapter:编写的Controller需要实现
HttpRequestHandler
接口,例子如下:
两个处理器适配器可以共存
注解的处理器映射器和处理器适配器
注解式开发在实际开发中非常常用,一般都是使用注解式开发,所以需要重点了解和掌握
在spring3.1之前使用DefaultAnnotationHandlerMapping
注解映射器,在spring3.1之后使用RequestMappingHandlerMapping
在spring3.1之前使用AnnotationMethodHandlerAdapter
注解适配器,在spring3.1之后使用RequestMappingHandlerAdapter
想要使用注解,我们需要在配置文件中开启注解:
或者直接开启注解驱动
然后我们直接Controller中加入注解@Controller
就可以使用了,不需要在实现接口,如下图:
然后我们在浏览器中就可以直接访问:http://localhost:8080/test
springmvc常用注解
- @Controller:注册bean到spring容器中,bean的id是类型首字母小写,也可以自己指定
- @RequestMapping:用来定义访问的url。可以是方法级别的,也可以是类级别的。两者可以协同工作,缩小选择范围。用法:
@RequestMapping(value="",method={"",""},headers={},params={"",""})
上面参数可不全部都设,其中
value:设置访问地址
method:设置访问方式,常用的method=RequestMethod.POST,和method=RequestMethod.GET
headers:头域,可以设置浏览器支持的格式
params:访问参数设置
- @Autowired:对成员变量、方法和构造函数进行标注,来完成自动装配工作。可以消除get,set方法。
- @ResponseBody:直接放在方法上,表示返回类型将会直接作为Http响应字节流输出,可以用于Ajax。
- @Valid:实体设置+类+类的引用,直接将页面中封装的实体对象信息封装@Valid后面定义的实体中。有了这个注解,就不用request.getParameter("")了,jsp页面上控件的name属性 跟实体字段一样,这样不用主动获取,就能自动的拿到页面控件的值了。
- @RequestParam:获取全局变量的值,用法:
@RequestParam(required=,value="",defaultValue="")
required:参数是否必须,boolean类型,默认为true
value:传递的参数名称,String类型,可选项,有值则对应方法的参数
defaultValue:参数没有传递时为参数默认指定的值
- @PathVariable:用于方法中的参数,表示方法参数绑定到地址URL的模板
springmvc封装参数
springmvc封装参数与struts2不同,springmvc基于方法进行封装参数,struts2基于属性进行参数封装,下面实现一个简单类型的参数封装例子:
首先在页面中定义:
然后在Controller方法中定义接受方法:
这里面有一个需要注意的是:页面中定义的参数的name和controller方法中的形参名称一样,如果不一样,需要用@RequestParam进行绑定,还有,最好使用包装类型。
pojo参数的封装跟上面的差不多,对应属性的名称在pojo里面的名称最好一样,这样可以自动封装进去。
针对特殊类型的参数,springmvc提供了converter(转换器)可以使用,还有在日期绑定等特殊格式的时候我们还可以自定义converter。
自定义converter步骤如下:
新建类实现converter接口:
然后在方法里面实现转换的逻辑
然后在spring-mvc.xml
文件里面配置:
如此,便可以实现自定义转换器,到这里就基本是springmvc的基础入门,后面会直接整合spring、mybatis一起来深入学习。