springMvc(1)

springmvc的简单配置

1.首先需要在web.xml中配置DispatcherServlet,这个类是springmvc的核心类,所以的操作都是由这里开始,并且大部分都是在这里面实现的,比如各种视图的解析,视图的

映射等等。配置文件:

    <servlet>
        <servlet-name>springServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

既然是和spring一套的,那肯定是有配置文件的,但是我们却没有配置文件路径,文件的默认路径是可以修改的,如果我们的这个文件没有配置路径的话,默认的路径是

/WEB-INF/springServlet-servlet.xml //  默认的路径就是:/WEB-INF/[servlet的名称]-servlet.xml 

但是我们是可以自己设置属性的,除了文件路径,还可以设置一下的几个属性:

contextClass:实现WebApplicationContext接口的类,当前的servlet用它来创建上下文。如果这个参数没有指定, 默认使用XmlWebApplicationContext。
contextConfigLocation:传给上下文实例(由contextClass指定)的字符串,用来指定上下文的位置。这个字符串可以被分成多个字符串(使用逗号作为分隔符) 来支持多个上下文(在多上下文的情况下,如果同一个bean被定义两次,后面一个优先)。
namespace:WebApplicationContext命名空间。默认值是[server-name]-servlet。

文件既可以放在WEB-INF下面,也可以放在classpath下面,比如:

<servlet>
     <servlet-name>springServlet</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>springServlet</servlet-name>
     <url-pattern>/</url-pattern>
 </servlet-mapping>

注意一点的是,这个classpath指的是编译后的位置,刚开始学习框架的时候,总会犯这样的错误,找不到配置文件,就是因为classpath的问题。

对于web项目,还有一种通用的写法,就是放在ContextLoaderListener下面:

restful风格的

  <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath*:/spring-context*.xml</param-value>
  </context-param>

支持多文件的:

<context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
          classpath:spring-common-config.xml,
          classpath:spring-budget-config.xml
      </param-value>
</context-param>

这样子,springmvc基本上是配置好了,这里没有讲spring的配置。

上面配置好了简单的web.xml以后,我们来讲一下DispatcherServlet.

从上面我们应该就明白了,其实它就是一个servlet,既然是servlet,那么理解起来就简单多了。

DispathcherServlet最主要的就是下面几个方法,下面一一来简单看看:

/**
     * Initialize the strategy objects that this servlet uses.
     * <p>May be overridden in subclasses in order to initialize further strategy objects.
     */
    protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

这个方法是初始化各种解析器,适配等等的方法,这个方法是在其父类的初始化方法中调用的,没记错的话,其实就是相当于Servlet的init方法执行时调用。首先一起了解下上面每一个方法初始化的都是什么:

1.MultipartResolver指的是文件上传解析类,对于文件上传的时候,需要使用到,我们看他的方法:
private void initMultipartResolver(ApplicationContext context) {
        try {        //这里获取bean   注意这个常量在前面的是定义的:MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";        //所以我们配置的时候  bean的名称必须是上面的这个  不然是不能识别的哦  注意咯
            this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
            }
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Default is no multipart resolver.
            this.multipartResolver = null;
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MultipartResolver with name ‘" + MULTIPART_RESOLVER_BEAN_NAME +
                        "‘: no multipart request handling provided");
            }
        }
    }

如果没有配置  那么默认就是没有文件上传解析的。这个时候,如果上传,那么会出一些问题的。

2.LocaleResolver这个是本地化解析,也就是做国际化的,如果没有设置,那么会默认为我们设置一个

3.ThemeResolver 看名字也知道,就是风格和主题解析类,默认也会有为我们设置一个

4.HandlerMappings :请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象;如BeanNameUrlHandlerMapping将URL与Bean名字映射,映射成功的Bean就是此处的处理器;从下面的代码中可以看出

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {    //请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器对象);        //如BeanNameUrlHandlerMapping将URL与Bean名字映射,映射成功的Bean就是此处的处理器,注意这里处理器值得是handler,而不是handlerMapping,形象的将     //就是handlerMapping是一个模板,处理器handler就是根据你的bean刻出的成型产品。
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name ‘" + getServletName() + "‘");
            }
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;
    }

5.HandlerAdapters:看到适配器了吧,对各种处理器包装成适配器,这样就能支持多种类型的处理器了。

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//将处理器进行包装,后面的操作都是都是由适配器进行工作

6HandlerExceptionResolvers:一场解析器,就比如出现错误的时候,可能统一调到某一个页面。默认也有实现,这个需求有太多中解决方案了,没什么好讲

7.RequestToViewNameTranslator:当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名;

8ViewResolvers:视图解析器。我们的配置中都会一般都会配置一个视图,就像这样:

        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="suffix" value=".jsp"></property>
            <property name="prefix" value="/WEB-INF/views/module/"></property>
        </bean>

视图解析器就是将上面的进行解析。超类只有一个方法

View resolveViewName(String viewName, Locale locale) throws Exception;
9.FlashMapManager值得是redirect的时候保存数据的一个相当于map分装的一个容器吧,但是官方是说在程序中一般不会使用的,比如在controller,就经常是用RedirectAttributes 来传输数据

讲完了几个比较重要的属性,然后将主要的几个放大,既然是servlet,那么我们就来看看service方法吧,这里的service是这样的:

protected void doService(HttpServletRequest request, HttpServletResponse response) 

里面有一个这样的依据代码需要引起重视,其他的代码都是配置一些属性什么的

try {
            doDispatch(request, response);
        }

这个方法其实就是DispatchServlet的核心,我们前面讲到的解析器,适配器等等都是在这里操作的:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
             HandlerExecutionChain mappedHandler = null;//前面讲过。handlerMapping映射成功,都会返回这个东西,其中包括处理器和拦截器
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {          //查看请求是否是Multipart(如文件上传)
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // Determine handler for the current request.                 //映射
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }
          //进行适配器的包装
                // Determine handler adapter for the current request.
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
         //
                applyDefaultViewName(request, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }             //解析视图  最终会调用view.render(mv.getModelInternal(), request, response);将model传进去
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }     //后面都是编译以后的一些操作了
        catch (Exception ex) {
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Error err) {
            triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }

上面也就简单的了解了一下springmvc的入口,接下来几天在研究一下springmvc其他的一些功能。好多东西都是自己理解的,不知道对不对==。

时间: 2024-08-04 20:51:16

springMvc(1)的相关文章

SpringMVC(6)文件上传

SpringMVC(6)文件上传 我们做一个上传图片的例子,页面(fileUpload.jsp)功能如下: 上传成功后即时显示上传的图片. upload.jsp: <body> <h3>文件上传</h3> <form action="/testAnnotationMVC_fileUpload/file/fileUpload2.jspx" method="post" enctype="multipart/form-d

SpringMVC(三)URL请求到Action的映射规则

在SpringMVC(二)经典的HelloWorld实现我们展示了一个简单的get请求,并返回了一个简单的helloworld页面.本篇我们来学习如何来配置一个action的url映射规则. 在SpringMVC(二)经典的HelloWorld实现我们在HelloWorldController上配置了一个@RequestMapping(value = "/helloworld")这表示对该controller的所有action请求必须是以"/helloworld"开

SpringMVC(四)数据绑定-1

在SpringMVC(三)URL请求到Action的映射规则我们介绍了请求是如何映射到一个action上的,下一步当然是如何获取到请求中的数据,这就引出了本篇所要讲的内容-数据绑定. 首先看一下都有哪些绑定数据的注解: [email protected],绑定单个请求数据,可以是URL中的数据,表单提交的数据或上传的文件: [email protected],绑定URL模板变量值: [email protected],绑定Cookie数据: [email protected],绑定请求头数据:

SpringMVC(五)数据绑定-2

在SpringMVC(四)数据绑定-1中我们介绍了如何用@RequestParam来绑定数据,下面我们来看一下其它几个数据绑定注解的使用方法. [email protected] 用来绑定URL模板变量值,这个我们已经在SpringMVC(三)URL请求到Action的映射规则中介绍了使用方法,这里不在赘述. [email protected] 用来绑定Cookie中的数据.下面我们用获取Cookie中的sessionId做测试: 在DataBindController添加cookiebind

SpringMVC(六)数据验证

在系列SpringMVC(四)数据绑定-1.SpringMVC(五)数据绑定-2中我们展示了如何绑定数据,绑定完数据之后如何确保我们得到的数据的正确性?这就是我们本篇要说的内容 -> 数据验证. 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先我们要到http://hibernate.org/validator/下载需要的jar包,这里以4.3.1.Final作为演示,解压后把hibernat

SpringMVC(7)格式化显示

在SpringMVC(六)数据验证中我们介绍了如何验证提交的数据的正确性,当数据验证通过后就会被我们保存起来.保存的数据会用于以后的展示,这才是保存的价值.那么在展示的时候如何按照要求显示?(比如:小数保留一定的位数,日期按指定的格式等).这就是本篇要说的内容->格式化显示. 从Spring3.X开始,Spring提供了Converter SPI类型转换和Formatter SPI字段解析/格式化服务,其中Converter SPI实现对象与对象之间的相互转换,Formatter SPI实现St

SpringMVC(8)国际化

在SpringMVC(七)格式化显示中我们讲了数据的格式化显示,Spring在做格式化展示的时候已经做了国际化处理,那么如何将我们网站的其它内容(如菜单.标题等)做国际化处理呢?这就是本篇要将的内容->国际化. 一.基于浏览器请求的国际化实现: 首先配置我们项目的springservlet-config.xml文件添加的内容如下: <bean id="messageSource" class="org.springframework.context.support

SpringMVC(三)

今天是学习Spring的第四天,今天终于又把Spring+SpringMVC+Mybatis(SSM)高了一遍,这次运行的代码和配置和昨天的不一样,今天运行的很成功. 主要学习的一点就是我今天使用的是自己的本地的一个MySQL数据库,所以用起来还算比较方便一点,比如自己创建的数据,这样自己对数据库也比较熟悉,不会像用网上的那些代码使用起来那么生疏,不过最主要在于目录结构还是不够很清楚,先占个位,以后再来补充起来关于目录结构的东西. 现在项目的底层的框架已经完成,跑跑简单的增删改查可以了.不明白的

SpringMVC(二)

今天在完成的工作的前提下,最终在睡觉前将SpringMVC和Mybatis整合了~~~ 其实就是按照从网上(参考http://www.toutiao.com/a6332703083554324737/)找到的教程自己做了一回,我的习惯是先做然后再深究: 1.创建工程(marven工程): 2.创建所需要的目录(如图): 3.各个文件所需要的代码如下: (1)spring-dao.xml <?xml version="1.0" encoding="UTF-8"?

Spring 源码分析(十)--SpringMVC(上篇)

Spring框架提供了构建Web应用程序的全功能MVC模块.通过策略接口,Spring框架是高度可配置的,而且支持多种视图技术.Spring MVC分离了控制器,模型对象,分派器以及处理程序对象的角色,这种分离让它们更容易进行定制. Spring的MVC是基于Servlet功能实现的,通过实现Servlet接口的DispatcherServlet来封装其核心功能实现,通过将请求分派给处理程序,同时带有可配置的处理程序映射,视图解析,本地语言,主题解析以及上载文件支持.默认的处理程序是非常简单的C