【Java】SpringMVC框架基础笔记

本文详细解析了SpringMVC框架的原理与配置,包括前端控制器、处理器映射器、适配器、视图解析器的工作流程,以及如何整合Mybatis、处理参数绑定、实现校验和异常处理。

目录

0.基本

0.0什么是SpringMVC

0.1框架原理

0.2Controller和Handler到底有什么区别

1.不使用注解的配置

1.1配置前端控制器

1.2配置处理器映射器(需要配置找到Handler通过的途径-->即不同的映射器不同途径)

1.3配置处理器适配器

1.4配置视图解析器

2注解的处理器映射器、处理器适配器

2,1注解使用的映射器:

2.2注解使用的适配器:

3.SpringMVC和Mybatis整合

4.参数绑定(如何接受request传来的东西)(简单类型、pojo)

4.1默认支持的类型

4.2简单类型的传入

4.3绑定pojo

4.4自定义参数绑定(Converter)

5.SpringMVC和Struts2区别

6SpringMVC校验(服务端校验)

6.0 校验页面提交的参数,使用hibernate的校验框架validation

6.1 步骤

7数据回显

7.2使用@ModelAttribute 指定pojo

7.2用@ModelAttribute("key")指定方法

7.3使用model来将pojo存储

8.全局异常处理器

9.json数据交互 

10.拦截器

10.1如何实现

10.2拦截器的配置

10.3拦截器执行顺序:


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 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值