Spring MVC一些配置信息解析

来源:互联网 发布:诈骗软件怎么举报 编辑:程序博客网 时间:2024/06/06 03:58

springMVC框架请求响应步骤

第一步:发起请求到前端控制器(DispatcherServlet

第二步:前端控制器请求HandlerMapping查找Handler

可以根据xml配置、注解进行查找

第三步:处理器映射器HandlerMapping向前端控制器返回Handler

第四步:前端控制器调用处理器适配器(HandlerAdapter)去执行Handler

第五步:处理器适配器去处理Handler

第六步:Handler处理完给适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView

第八步:前端控制器请求视图解析器去进行视图解析

根据逻辑视图名解析成正在的视图(如jsp

第九步:视图解析器向前端控制器返回view

第十步:前端控制器进行视图渲染

视图渲染将模型数据(在ModelAndView对象中)填充到request

第十一步:前端控制器向用户响应结果

 

 

DispatcherServlet

使用Spring MVC,配置DispatcherServlet是第一步。

DispatcherServlet是一个Servlet,所以可以配置多个DispatcherServlet。是通过名字来区分的。每一个DispatcherServlet有自己的WebApplicationContext上下文对象.

DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(我们写的Action)来处理。

在DispatcherServlet的初始化过程中,如果没有手动配置路径,默认情况下框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean

 

另外一个:

<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*:/springMVC.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>springMVC</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

指明了配置文件的文件名,不使用默认配置文件名,而使用springMVC.xml配置文件。

其中<param-value>**.xml</param-value> 这里可以使用多种写法
1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
3、<param-value>classpath*:springMVC-mvc.xml</param-value>
4、多个值用逗号分隔

 

 

配置springMVC前端控制器DispatcherServlet

<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-value>classpath*:spring/applicationContext-mvc.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

 

 

<servlet-mapping>

<servlet-name>springMVC</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

这里的url-pattern规则:

第一种:*.action; 访问以.action结尾的由DispatcherServlet进行解析

第二种:/;所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析,使用此种方式可以实现restful风格的URL

第三种:/*;这样的配置不对,使用这种配置,最终要转发到一个jsp页面的时候,任然会由DispatcherServlet进行解析jsp,不能根据jsp找到handler


Spring MVC的自动转换功能 HttpMessageConverter

默认起用的MVC注解功能

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">

 

StringHttpMessageConverter that can read and write Strings from the HTTP request and  response.

FormHttpMessageConverterthat can read and write form data from the HTTP request  and response.

ByteArrayMessageConverterthat can read and write byte arrays from the HTTP request  and response.

MarshallingHttpMessageConverterXML的转换需要使用Spring Marshaller  Unmarshaller.

MappingJacksonHttpMessageConverterJSON的转换.

SourceHttpMessageConverter:能够读/写来自HTTP的请求与响应的 javax.xml.transform.Source ,支持 DOMSource, SAXSource,  StreamSource  XML格式

BufferedImageHttpMessageConverterthat can read and  write java.awt.image.BufferedImage from the HTTP  request and response

 

 

<bean class="org.springframework.http.converter.StringHttpMessageConverter">

<property name="supportedMediaTypes">    

       <list> 

              <value>text/plain;charset=UTF-8</value>

              <value>application/json;charset=UTF-8</value>

         </list>    

     </property> 

</bean> 

supportedMediaTypes
意思是被支持的媒体类型,该bean中配置的就是被支持的媒体类型

text/html是以html的形式输出,比如<input type="text"/>就会在页面上显示一个文本框,而以plain形式就会在页面上原样显示这段代码

 

 

<context:component-scan>使用说明

如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。另外<context:annotation-config/>还提供了两个子标签

1.        <context:include-filter>

2.       <context:exclude-filter>

在说明这两个子标签前,先说一下<context:component-scan>有一个use-default-filters属性,改属性默认为true,这就意味着会扫描指定包下的全部的标有@Component的类,并注册成bean.也就是@Component的子注解@Service,@Reposity等。所以如果仅仅是在配置文件中这么写

<context:component-scan base-package="tv.huan.weisp.web"/>

 Use-default-filter此时为true那么会对base-package包或者子包下的所有的进行java类进行扫描,并把匹配的java类注册成bean

可以发现这种扫描的粒度有点太大,如果你只想扫描指定包下面的Controller,该怎么办?此时子标签<context:incluce-filter>就起到了勇武之地。如下所示

<context:component-scan base-package="tv.huan.weisp.web .controller">  

<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   

</context:component-scan>  

这样就会只扫描base-package指定下的有@Controller下的java类,并注册成bean

但是因为use-dafault-filter在上面并没有指定,默认就为true,所以当把上面的配置改成如下所示的时候,就会产生与你期望相悖的结果

<context:component-scan base-package="tv.huan.weisp.web ">  

<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   

</context:component-scan>  

此时,spring不仅扫描了@Controller,还扫描了指定包所在的子包service包下注解@Servicejava

此时指定的include-filter没有起到作用,只要把use-default-filter设置成false就可以了。这样就可以避免在base-packeage配置多个包名这种不是很优雅的方法来解决这个问题了。

<context:component-scan base-package="tv.huan.weisp.web " use-default-filters="false">  

<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   

</context:component-scan>  

另外在我参与的项目中可以发现在base-package指定的包中有的子包是不含有注解了,所以不用扫描,此时可以指定<context:exclude-filter>来进行过滤,说明此包不需要被扫描。综合以上说明

Use-dafault-filters=false”的情况下:<context:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描

 

 <mvc:annotation-driven />注解意义

<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMappingAnnotationMethodHandlerAdapter 两个bean,spring MVC@Controllers分发请求所必须的。
并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。

DefaultAnnotationHandlerMapping ->  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping 
AnnotationMethodHandlerAdapter ->  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 

<mvc:message-converters>:允许注册实现了HttpMessageConverter接口的bean,来对requestbody 或 responsebody中的数据进行解析

 <mvc:interceptor>

<mvc:interceptor>这个标签用于注册一个自定义拦截器或者是WebRequestInterceptors.可以通过定义URL来进行路径请求拦截.定义的拦截器只需要实现,自定义一个拦截器,要实现HandlerInterceptor接口:

public class AuthInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler){}

@Override

public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) {}

 @Override

public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {}

}

(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

   (2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。

   (3 )afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

 

 <mvc:mapping path="/**"/>

/**  的意思是所有文件夹及里面的子文件夹
/*  是所有文件夹,不含子文件夹
/   web项目的根目录

 

配置viewResolver

首先必须要先配置velocityConfigurer

<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">

<property name="resourceLoaderPath" value="/WEB-INF/views" />

<property name="velocityProperties">

<props>

<prop key="directive.foreach.counter.name">loopCounter</prop>

<prop key="directive.foreach.counter.initial.value">1</prop>

<prop key="input.encoding">UTF-8</prop>

<prop key="output.encoding">UTF-8</prop>

</props>

</property>

</bean>

resourceLoaderPath指定页面存放的文件夹,会自动到这个文件夹下找文件

第二处主要制定编码,防止页面出现乱码的情况,虽然在srcvelocity.properties里也指定了编码但还是出现乱码的情况,这边重新指定。

 

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">

          <property name="cache" value="false" /><!--是否缓存模板-->

          <property name="prefix" value="" />

          <property name="suffix" value=".vm" />

          <property name="toolboxConfigLocation" value="/WEB-INF/toolbox.xml" /><!--toolbox配置文件路径-->

          <property name="dateToolAttribute" value="date" /><!--日期函数名称-->

          <property name="numberToolAttribute" value="number" /><!--数字函数名称-->

          <property name="contentType" value="text/html;charset=UTF-8" />

          <property name="exposeSpringMacroHelpers" value="true" /><!--是否使用spring对宏定义的支持-->         

          <property name="exposeRequestAttributes" value="true" /><!--是否开放request属性-->

          <property name="requestContextAttribute" value="rc"/><!--request属性引用名称-->

          <property name="layoutUrl" value="templates/layout/default.vm"/<!--指定layout文件-->

   </bean>

 


后续的一些笔记会了解之后再添加进来

 

 

 

 

 

 

 

 

0 0
原创粉丝点击