目录
1.2配置处理器映射器(需要配置找到Handler通过的途径-->即不同的映射器不同途径)
4.参数绑定(如何接受request传来的东西)(简单类型、pojo)
6.0 校验页面提交的参数,使用hibernate的校验框架validation
7.2用@ModelAttribute("key")指定方法
0.基本
0.0什么是SpringMVC
Spring的一个框架,和Spring无需通过中间整合层进行整合,是一个web框架
0.1框架原理
1)发起请求url到①前端控制器(DispatcherServlet)
2)前端控制器请求②处理器映射器(HandlerMapping)通过url查找③Handler处理器(可以根据XML配置、注解进行查找)
3)返回执行链(HandlerExecutionChain){Interceptor / Handler}给前端控制器
4)前端控制器调用④处理器适配器(HandlerAdapter)=Controller执行Handler
5)处理器适配器执行Handler,执行完得到ModelAndView(SpringMVC的底层对象)
6)处理器适配器向前端返回控制器返回ModelAndView
7)前端控制器请求⑤视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的⑥视图(View)
8)视图解析器向前端控制器返回视图
9)前端控制器进行视图渲染,即将模型数据(在ModelAndView对象中)填充到request域
10)前端控制器向用户响应结果
①前端控制器(DispatcherServlet):接收request,响应response,相当于转发器
②处理器映射器(HandlerMapping):根据请求的url来查找Handler
③Handler(处理器):按照HandlerAdapter要求的规则来编写代码
④处理器适配器(HandlerAdapter):按照特定规则(HandlerAdapter要求的规则)去执行Handler
⑤视图解析器(ViewResolver):进行视图解析,根据逻辑视图名解析成真正的视图(View)
⑥视图(View):是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)
0.2Controller和Handler到底有什么区别
Controller是类,Handler是Controller里面的方法
1.不使用注解的配置
1.1配置前端控制器
contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)
<!-- springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
使用此种方式可以实现 RESTful风格的url
第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时, 仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。 -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
1.2配置处理器映射器(需要配置找到Handler通过的途径-->即不同的映射器不同途径)
<!-- 配置handler -->
<bean id="handlerid" class="handler的类路径/>
<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="mappings">
<props>
<prop key="/handler.action">handlerid</prop>
<props>
<property>
</bean>
或
<!-- 配置handler -->
<bean name="/handler.action" class="handler的类路径"/>
<!-- 这个也可以 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- BeanNameUrl == 配置Handler这个Bean,其中Bean的属性name作为Url -->
多个映射器可以并存,前端控制器判断url能让哪些映射器处理,会让正确的映射器处理
1.3配置处理器适配器
在上面配置的servlet-name+.xml中 即 springmvc.xml中配置
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
或
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
通过查看源代码可以知道,所有的适配器都需要实现接口HandlerAdapter
里面有一个方法 boolean supports(Object handler)
可以查看此适配器支持 实现哪个接口的Handler
*eg:第一个适配器支持实现了Controller接口的Handler
public boolean supports(Object handler){
return (handler instanceof Controller);
}
第二个适配器支持实现了HttpRequestHandler接口的Handler
1.4配置视图解析器
可以配置两个属性,当ModelAndView.setView("...")指定路径的时候就可以省略前缀和后缀
<bean class="org.springframework.web.serlvet.view.InternalResourceViewResolver">
<property name="prefix" value="...前缀..."/>
<property name="suffix" value="...后缀..."/>
</bean>
2注解的处理器映射器、处理器适配器
前端控制器从DispatcherServlet.properties中加载处理映射器、适配器、视图解析器等组件,
如果不在springmvc.xml中配置,使用默认加载的。
2,1注解使用的映射器:
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。
2.2注解使用的适配器:
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。
注解的映射器和适配器必须配套使用,非注解的就不用配套使用
然后在springmvc中配置需要的映射器和适配器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
(可使用标签<mvc:annotaion-driven></mvc:annotaion-driven>代替上述配置吗,会附加其他更多的配置:如json解析)
注解:
@Controller:用于标识这是一个控制器
@RequestMapping(value="..",method={RequestMethod.POST})
:在控制器里面的方法加这个注解,用于标识此方法对应的url路径
value用于窄化请求映射:即到这个Controller之前要加value里面的路径
method用于限制HTTP请求方法
3.SpringMVC和Mybatis整合
spring的监听器
将mapper/service/controller加载到spring容器中
<!-- 加载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>
Controller传回的三种参数:
①ModelAndView-->.addObject() 和 .setViewName()来传回数据
②String-->返回值就是View(视图名-->页面路径)可以重定向"redirect:....."也可以转发"forward:....."
Model通过修改传入的形参Model来进行返回
③void-->通过形参比如定义request和response来传数据
4.参数绑定(如何接受request传来的东西)(简单类型、pojo)
早期使用PropertyEditor(只能将字符串传承Java对象)
后期使用Converter(支持任意类型)
4.1默认支持的类型
(HttpServletRequest、HttpServletResponse、HttpSession、Model/ModelMap),即需要使用时作为参数传入即可
4.2简单类型的传入
要求request传入参数名称和controller方法中传入的参数名称一致,也可以直接通过Controller方法传参来使用页面中传入的参数
@RequestParam(value=""):使用此注解名称就可以不一致,用value里面的值来进行绑定
*eg:@RequsetParam(value="id")Integer userid,这样就将页面传入的参数id和Controller中方法的userid绑定在一起了
此注解还有两个参数required=""是否必须传入参数(不传报错)、defaultValue=""(默认值)
4.3绑定pojo
要求:页面中input的name和Controller的pojo形参的属性的名字一致
4.4自定义参数绑定(Converter)
类型转换器(Converter)需要实现接口Converter<S,T> S是原始类型,T是需要转化的类型
配置类型转换器
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 转换器 -->
<property name="converters">
<list>
<bean class="...类型转换器类路径..."/>
</list>
</property>
</bean>
注入到适配器
两种方式:
①mvc:annotation声明适配器的配置方式
conversionService-->通过conversion-service标签注入适配器
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
②不用mvc标签声明适配器的方式
conversionService-->注入到webBinding-->注入到适配器HandlerAdapter
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
<!-- 自定义webBinder -->
<bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService" />
</bean>
<!-- conversionService -->
5.SpringMVC和Struts2区别
- springmvc基于方法开发的(参数在形参里面-->类似于Service的开发方式),struts2基于类开发的(参数在成员变量里面)。
- springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。
方法执行结束,形参数据销毁。
- springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。
------------------------------------------------
------------------------------------------------
参数绑定(集合类型)
list、map:返回的pojo对象中有对应的list或map属性
页面中input的name和pojo集合里的对象对应的属性名一致
6SpringMVC校验(服务端校验)
6.0 校验页面提交的参数,使用hibernate的校验框架validation
6.1 步骤
- 配置校验器
<!-- 校验器 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- hibernate校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<!-- 校验错误信息配置文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 资源文件名-->
<property name="basenames">
<list>
<value>classpath:CustomValidationMessages</value>
</list>
</property>
<!-- 资源文件编码格式 -->
<property name="fileEncodings" value="utf-8" />
<!-- 对资源文件内容缓存时间,单位秒 -->
<property name="cacheSeconds" value="120" />
</bean>
CustomValidationMessages是用于存放错误信息的XML文件
---->key-value格式:key是类似于错误信息的id,value就是错误信息
- 注入到适配器:两种方式
①mvc
<mvc:annotation-driven validator="validator"> </mvc:annotation-driven>
②不用mvc标签声明适配器的方式
<!-- 自定义webBinder -->
<bean id="customBinder"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" />
</bean>
<!-- 注解适配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
- 对于需要校验的pojo属性添加校验规则
@Size(min=1,max=30,message="{item.name.length.error}")
private String name;
@NotEmpty(message="{pic.is.null}")
private String pic;
- 规则的分组:
写一个没有任何方法的接口(eg:public Interface ValidGroup1)
可以通过添加属性group={ValidGroup1}将规则加到此分组中
在需要校验的参数前@Validated(value={"ValidGroup1"})
- 需校验的pojo前加@Validated,后面添加形参BindingResult bindingResult
public String editItemSubmit(@Validated Items items,BindingResult result)
{...}
- 通过参数result来获取错误的信息
List<ObjectError> errors = result.getAllErrors();
7数据回显
SpringMVC默认对pojo数据进行回显,pojo数据传入Controller方法后,SpringMVC会自动把pojo对象放到request域中
7.2使用@ModelAttribute 指定pojo
回显到页面在request中的key
eg:public String editSomething(@ModelAttribute("beannnn") Bean bean);
页面: beannnn.属性
如果不使用注解,就只能 bean.属性
7.2用@ModelAttribute("key")指定方法
将方法的返回值返回到页面
7.3使用model来将pojo存储
model.addAttribute();
8.全局异常处理器
Dao层出现的异常-->Service层(出现的异常)-->Controller(出现的异常)
---->所有异常都给前端控制器的异常处理器ExceptionResolver
定义一个类实现HandlerExceptionResolver接口就是全局异常处理器
eg:
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
//handler就是处理器适配器要执行Handler对象(只有method)
//ex就是捕捉到的异常
}
还要在Spring配置文件中配置该类
9.json数据交互
@requestBody:将json转成java对象
@responseBody:将java对象转成json
通过第三方的json转换器(jackson)
10.拦截器
10.1如何实现
针对HandlerMapping进行拦截设置
实现HandlerInterceptor接口
重写三个方法
//进入 Handler方法之前执行
//用于身份认证、身份授权
//比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//return false表示拦截,不向下执行
//return true表示放行
}
//进入Handler方法之后,返回modelAndView之前执行
//应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
//执行Handler完成执行此方法
//应用场景:统一异常处理,统一日志处理
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor1...afterCompletion");
}
10.2拦截器的配置
①第一种:
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
②第二种:全局配置 /**表示所有url包括子url路径
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.ssm.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.ssm.interceptor.HandlerInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.ssm.interceptor.HandlerInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
10.3拦截器执行顺序:
eg:定义的时候 拦截器1在前 拦截器2在后
(pr-->preHandle()、po-->postHandle()、af-->afterCompletion)
- 两个拦截器都放行
1pr-->2pr-->2po-->1po-->2af-->1af
- 1放行,2不放行
1pr-->2pr-->1af
- 1不放行,2不放行
1pr
本文详细解析了SpringMVC框架的原理与配置,包括前端控制器、处理器映射器、适配器、视图解析器的工作流程,以及如何整合Mybatis、处理参数绑定、实现校验和异常处理。
4175

被折叠的 条评论
为什么被折叠?



