Spring-MVC

SpringMVC

springmvc和spring framework一起发布,并且springmvc是基于servlet的原始web框架,最早springmvc是叫做springwebmvc源自于代码模块spring-webmvc。

核心

DispatcherServlet(前端控制器):为Request请求提供共享算法,但是实际的工作被可配置委托组件完成。前端控制器像任意一个servlet一样。需要被声明,和映射通过java配置的方式或者web.xml传统方式。前端控制器使用 Spring 配置来发现请求映射、视图解析、异常处理所需的委托组件。

Context的层次

配置方式

这是基于java配置的方式之一:

这个可以使得springmvc的开发完全基于java代码不用去编写配置文件,但是这个配置有局限性,就是很多事情Spring帮我们做了,但是我们并不知道做了那些事情,如果要扩展功能,就会有限制。

所以最好还是使用XML文件的配置方式去配置DispatchServlet。

/*通过继承AbstractAnnotationConfigDispatcherServletInitializer类来简化配置,这个是WebApplicationInitializer接口的实现类,WebApplicationInitializer是springmvc提供的一个接口,确定检测到你的实现,和自动用于初始化任何Servlet3容器.
*/
package cn.wangmyi.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class DispatchServletConig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{ServletBean.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

这个xml配置的方式:

<web-app>
    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--这个的默认地址是/WEB-INF/app-context.xml配置文件-->
            <param-value>这里是前端控制器的配置元数据的配置路径</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
    </servlet-mapping>
</web-app>

DispatcherServlet处理一个请求的流程

DispatcherServlet处理一个请求

  1. 在request请求中WebApplication被搜索并绑定为一个属性,在过程中controller或者其他元素可以使用
  2. locale resolver绑定到request中,让在解析locale的过程中的元素去使用,当处理请求时,如果不需要locacle解析,就不需要这个。
  3. 绑定主题解析器到lrequest中,让试图取使用。不用这个可以忽略。
  4. 如果有指定一个multipart file resolver,由于multiparts,request将被检查。如果发现request中包含multipart,它就会被包装到成MultipartHttpServletRequest进入更进一步被其他在过程中的元素处理。
  5. 合适的handler查找(HandlerMapping的工作),如果找到与handler有关的执行链就会执行取准备一个模型(modle)用于渲染,或者如果handler有被注解@ResponseBody那么响应将直接被渲染取代视图的渲染。
  6. 如果model被返回了,试图就被渲染,如果没有就没有试图被渲染,因为了请求已经被完成了。

  1. 所有的请求都要先经过前端控制器,然后前端控制器把单个实例的请求委托给其他的组件来执行。
  2. Dispatcher查询映射处理器确定应该去哪个控制器
  3. 选择好控制器之后,讲请求发送给控制器,控制器处理请求。
  4. 请求通过讲数据绑定到模型上,再指定视图名,发送回DispatcherServlet。
  5. DispatcherServlet调用视图解析器将控制器传回的试图名字进行匹配,找到一个特定的视图。
  6. DispatcherServlet渲染视图,就是把模型数据绑定到视图上
  7. 向客户端相应请求。就是把视图传送回去。

Web MVC Config的配置

Application 可以声明处理请求所需要的基础Bean。DispatcherServlet回去WebApplicationContext里面找特殊的Bean——就是处理请求所需要的基础Bean——如果我们没有·给DispatcherServlet提供,那么它就会使用默认的类型。在DispatcherServlet.proerpties文件里的属性。

基本的Bean

Bean type Explanation
HandlerMapping 将一个请求映射到一个连同用作前置和后置处理的拦截器一起的handler。映射基于特定一些标准,具体的根据HandlerMapping的实现而定。
HandlerAdapter 在HandlerMapping找到handler之后,HandlerAdapter将帮助DispatcherServlet调用被映射的handler处理请求,不管它是如何被调用的。HandlerMapping主要是为了在一些细节上隐藏DispatcherServlet。这个就是处理例如@ResponseBody的,如果被这个注解了那么就不调用试图解析器了。
HandlerExceptionResolver 解析异常的策略,可能将他们映射到处理器或者映射到一个错误的页的HTML,或者其他目标。
ViewResolver 将一个从handler返回的基于String的视图名到一个真正的视图并渲染他们响应回去。
ThemeResolver 解析你的web应用使用的主题。
MultipartResolver spring提供的多文件上传的帮助库。

基于Java配置DispatchServlet的方法:

实现WebApplicationInitializer接口。

这个接口是确保你实现是可以被探测到并且可以自动使用去初始化Servlet3容器的。


import org.springframework.web.WebApplicationInitializer;

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}

使用Spring提供的WebApplicationInitializer实现类AbstractDispatcherServletInitializer可以更简单的的去注册DispatcherServlet,(这个是基于java配置Mvc推荐的方法) 可以通过继承已经继承了AbstractDispatcherServletInitializer的

AbstractAnnotationConfigDispatcherServletInitializer 去初始化DispatcherServlet,这个只要提供两个上下文的实现类——ServletApplicationContext和RootApplicationContext的类的类对象就可以。

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { MyWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

基于XML-based Spring configuration

需要直接继承AbstractDispatcherServletInitializer。这个方式提供添加Filter实例,并且自动映射到DIspatcherServlet中。

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

	@Override
    protected Filter[] getServletFilters() {
        return new Filter[] {
            new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
    }
}

使用web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/web/RootApplicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class> 
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>dispactcherServelet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/web/WebApplicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispactcherServelet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
posted @ 2021-10-05 21:12  _LittleBee  阅读(32)  评论(0编辑  收藏  举报