Spring MVC简介与DispatcherServlet.md


该文档参考自Spring Framework 5.0.9

1.Spring Web MVC

1.1.Introduction

Spring Web MVC是构建在Servlet API上的原始Web框架,从一开始就包含在Spring Framework中。 正式名称“Spring Web MVC”来自其源模块spring-webmvc的名称,但它通常被称为“Spring MVC”

与Spring Web MVC并行,Spring Framework 5.0引入了一个反应式堆栈(reactive stack),Web框架,其名称Spring WebFlux也基于其源模块spring-webflux。 本节介绍Spring Web MVC。 下一节将介绍Spring WebFlux。

Spring Web MVC是一种基于 Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web 开发的。

Spring Web MVC也是服务到工作者模式的实现,但可进行优化。

1.2.DispatcherServlet

  • 前端控制器是DispatcherServlet

  • 应用控制器其实拆为处理器映射器(Handler Mapping )进行处理器管理和视图解析器(View Resolver )进行视图管理;

  • 页面控制器/动作/处理器为Controller 接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO 类);支持本地化 (Locale) 解析、主题(Theme) 解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;

  • 提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

  • SpringMVC提供了一个功能强大的,通用的DispatcherServlet,也叫前端控制器,可以接收整个项目的所有请求;

  • DispatcherServletSpringMVC为我们写好的Servlet,所有的请求都经过它来调用控制器中的方法并处理;

  • DispatcherServletSpringMVC定义,由SpringIOC容器管理;

像许多其他Web框架一样,Spring MVC围绕前端控制器模式进行设计,其中中央Servlet DispatcherServlet为请求与处理提供共享算法,而实际工作则委托给可配置的组件执行。 该模型非常灵活,支持多种工作流程。

作为任意的ServletDispatcherServlet需要根据Servlet的规范,使用Java配置或在web.xml中进行声明和映射。DispatcherServlet根据Spring规范的配置来确认它在请求映射,查看解析,异常处理等方面所需的委托组件,and more

因为Servlet要被SpringIOC容器管理,所以要在产生Servlet实例的时候就要产生SpringIOC容器的实例。以下是注册和初始化DispatcherServlet的Java Config示例。 该类由Servlet容器自动检测(请参阅Servlet Config):

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

除了直接使用ServletContext API之外,您还可以扩展AbstractAnnotationConfigDispatcherServletInitializer并覆盖特定方法(请参阅Context Hierarchy下的示例)。

web.xml中配置该Servlet的启动时机与初始化参数:

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

</web-app>
  • 启动时机:<load-on-startup>配置DispatcherServletWeb服务器已启动就将该Servlet实例化;
  • 初始化参数:在<init-param>中定义SpringIOC的配置文件路径,这样在Servlet被实例化的时候,该路径就会被Servlet通过ServletConfig参数获取到,获取到之后就可以获取该文件并解析实例化bean,那么Spring容器就也被实例化了;
  • 此处也可以不使用<init-param>配置,但是要求Spring配置文件必须放在WEB-INF下,并且文件名与servlet-name一致;
  • DispatcherServlet可能要让控制器调用任意的实体类,所以必须一开始就初始化Spring容器;

Spring Boot 遵循不同的初始化顺序。Spring Boot使用Spring配置来引导自身和嵌入的Servlet容器,而不是hook到Servlet容器的生命周期。 在Spring配置中检测到FilterServlet声明,并在Servlet容器中注册。 有关更多详细信息,请查阅Spring Boot文档。

1.2.1Context Hierarchy - 上下文层次结构

DispatcherServlet需要一个WebApplicationContext(一个普通的ApplicationContext的扩展)用于其自己的配置。WebApplicationContext有一个指向它所关联的ServletContextServlet的链接。它也绑定到ServletContext,以便应用程序可以在需要访问它的时候使用RequestContextUtils上的静态方法访问WebApplicationContext

对于许多应用程序来说具有单个WebApplicationContext更为简洁。当然也可以有一个上下文层次结构(Context Hierarchy),其中一个根WebApplicationContext通过多个DispatcherServlet(或其他Servlet)实例共享,每个实例都有其自己的子WebApplicationContext配置。有关上下文层次结构功能的更多信息,请参阅 Additional Capabilities of the ApplicationContext的其他功能。

WebApplicationContext通常包含需要跨多个Servlet实例共享的基础架构bean,例如数据存储库和业务服务。这些bean被有效地继承,并且可以在特定的Servlet的子WebApplicationContext中被重写(即重新声明),子WebApplicationContext通常包含给定的Servlet本地的bean:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xmfw1zdy-1572859654839)(https://docs.spring.io/spring/docs/5.0.7.BUILD-SNAPSHOT/spring-framework-reference/images/mvc-context-hierarchy.png)]

以下是使用WebApplicationContext层次结构的示例配置:

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

如果不需要应用程序上下文层(context hierarchy)次结构,则应用程序可以通过getRootConfigClasses()返回所有配置,并且可以从getServletConfigClasses()返回null

等效于在web.xml中:

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app1-context.xml</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>

如果不需要应用程序上下文层次结构(context hierarchy),则应用程序可以仅配置“root”上下文,并将contextConfigLocation Servlet参数留空。

1.2.2.Special Bean Types - 特殊Bean类型

DispatcherServlet 委托特殊的bean来处理请求并呈现适当的响应。“special bean”是指实现WebFlux框架协议的Spring管理的对象实例。这些bean通常带有内置了一些规则,但您可以自定义其属性,扩展或替换它们。

下表列出了DispatcherHandler检测到的特殊bean

Bean type说明
HandlerMapping将请求映射到处理程序(handler)以及预处理和后处理的 interceptors 列表。 该映射基于一些标准,其细节因HandlerMapping实现而不同。 两个主要的HandlerMapping实现是RequestMappingHandlerMapping,它支持@RequestMapping注解方法,SimpleUrlHandlerMapping, 它为URI处理程序显式注册URI路径模式。
HandlerAdapter帮助DispatcherServlet调用请求映射到的处理程序(handler), 而不管实际如何调用处理程序(handler)。 例如,调用带注解的控制器需要解析注解。 HandlerAdapter的主要目的是屏蔽DispatcherServlet的细节。
HandlerExceptionResolver它是异常解决机制, 可能将异常映射到处理程序或HTML错误视图或其他。 参考 Exceptions.
ViewResolver将从处理程序返回的基于字符串的逻辑视图名称解析为实际视图,以便使用返回的响应。 参考 View ResolutionView Technologies.
LocaleResolver, LocaleContextResolver解析Locale 客户端正在使用以及可能的时区,以便能够提供国际化的视图。 参考Locale.
ThemeResolver解析您的Web应用程序可以使用的主题,例如提供个性化布局。参考 Themes.
MultipartResolvermultipart解析库的帮助下解析multi-part请求的抽象(例如,浏览器表单文件上载)。 参考 Multipart resolver.
FlashMapManager存储和检索可用于将属性从一个请求传递到另一个请求的“input”“output”FlashMap,通常通过重定向。 参考Flash attributes.

1.2.3.Web MVC Config

应用程序可以声明Special Bean Types中的基础架构Bean列表,用于处理请求所需。DispatcherServlet检查每个特殊beanWebApplicationContext。如果没有匹配的bean类型,则它就是DispatcherServlet.properties中列出的默认类型。

最好使用MVC Config,它用Java或XML声明所需的bean,并提供更高级别的配置回调API来自定义它。可查看MVC Config。

Spring Boot依靠MVC Java Config来配置Spring MVC,并且还提供了许多额外的方便选项。

1.2.4.Servlet Config - Servlet配置

在Servlet 3.0+环境中,您可以选择以编程方式将Servlet容器配置作为替代方式或与web.xml文件组合使用。 以下是注册DispatcherServlet的示例:

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("/");
    }
}

WebApplicationInitializer是Spring MVC提供的一个接口,它确保您的实现被检测到并自动用于初始化任何Servlet 3容器。还有一个名为AbstractDispatcherServletInitializerWebApplicationInitializer的抽象基类实现更容易注册DispatcherServlet,通过简单重写方法来指定Servlet映射和DispatcherServlet配置的位置。

建议使用基于Java的Spring配置的应用程序:

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的Spring配置,则应该直接从AbstractDispatcherServletInitializer扩展:

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[] { "/" };
    }
}

AbstractDispatcherServletInitializer还提供了一种便捷方式,用于添加Filter实例并将其自动映射到DispatcherServlet

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    // ...

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

每个filter都会根据其具体类型添加一个默认名称,并自动映射到DispatcherServlet

AbstractDispatcherServletInitializerisAsyncSupported提供了一个标志来启用DispatcherServlet上的异步支持以及映射到它的所有过滤器。 默认情况下,该标志被设置为true

最后,如果您需要进一步自定义DispatcherServlet本身,则可以覆盖createDispatcherServlet方法。

1.2.5.Processing - 处理过程

DispatcherServlet 按如下方式处理请求:

  • WebApplicationContext在请求中被搜索并绑定,作为控制器和进程中其他元素可以使用的属性。 WebApplicationContextDispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE关键字下被默认绑定。
  • locale resolver绑定到请求以启用进程中的元素来resolve(解析)处理请求(呈现视图,准备数据等)时要使用的locale(区域)。如果你不需要locale resolving(区域解析),那就不需要locale resolver。
  • theme resolver`被绑定到请求,让请求等元素去决定该使用哪个theme(主题),如果不需要可以忽略theme resolver。
  • 如果你指定了multipart file resolver,则会检查请求中的multiparts,如果找到multiparts,则将请求封装在MultipartHttpServletRequest中,以供进程中的其他元素进一步处理。See Multipart resolver for further information about multipart handling.
  • 搜索适当的处理程序(handler)。如果找到处理程序(handler),则会执行与该处理程序(handler)(预处理程序,后处理程序和控制器)关联的执行链以准备模型(model)或渲染。
  • 如果返回模型(model),则呈现视图(view)。如果没有返回model(可能是由于预处理程序或后处理程序拦截了请求,可能出于安全原因),则不会呈现视图,因为请求可能已经被满足。

WebApplicationContext中声明的HandlerExceptionResolver bean用于解决请求处理期间抛出的异常。这些exception resolver允许定制逻辑来解决异常。参考Exceptions

Spring DispatcherServlet支持返回最后修改日期,正如Servlet API所指定的那样。确定特定请求的最后修改日期的过程很简单:DispatcherServlet查找适当的处理程序映射(handler mapping)并测试找到的处理程序(handler)是否实现LastModified接口。如果是,则LastModified接口的long getLastModified(request)方法的值将返回给客户端。

您可以通过将Servlet初始化参数(init-param元素)添加到web.xml文件中的Servlet声明来自定义单个DispatcherServlet实例。请参阅下表以获取支持的参数列表。

Parameter说明
contextClass实现WebApplicationContext的类,它实例化此Servlet使用的上下文。 默认情况下,使用XmlWebApplicationContext
contextConfigLocation传递给上下文实例(由contextClass指定)的字符串,用于指示可以找到上下文的位置。 该字符串可能包含多个字符串(使用逗号作为分隔符)以支持多个上下文。如果多个上下文位置中定义了两次bean,最新的位置优先。
namespaceWebApplicationContext的命名空间。 默认为[servlet-name] -servlet
throwExceptionIfNoHandlerFound当找不到处理请求的handler时是否抛出NoHandlerFoundException。 然后可以用HandlerExceptionResolver捕获异常,例如:通过@ExceptionHandler控制器方法,并像其他handler一样进行处理。 默认情况下,它被设置为“false”,在这种情况下,DispatcherServlet将响应状态设置为404(NOT_FOUND)而不引发异常。 请注意:如果还配置了default servlet处理,则未解析的请求将始终转发到default servlet,并且永远不会引发404

1.2.6.Interception - 拦截器

所有的HandlerMapping实现都支持处理程序拦截器,当你想要将特定功能应用于某些请求时,例如,检查委托人。拦截器(Interceptor)必须使用三种方法来实现org.springframework.web.servlet包中的HandlerInterceptor,这些方法应该提供足够的灵活性来执行各种预处理(pre-processing)和后处理(post-processing):

  • preHandle(..) — 在实际的处理程序(handler)执行之前
  • postHandle(..) — 在实际的处理程序(handler)执行之后
  • afterCompletion(..) — 在完成请求完成后

preHandl() 方法返回一个布尔值。您可以使用此方法来中断或继续处理程序执行链。当此方法返回true时,处理程序执行链将继续; 当它返回false时,DispatcherServlet假定拦截器本身已经处理请求(并且例如呈现适当的视图)并且不继续执行执行链中的其他拦截器和实际处理器。

有关如何配置拦截器的示例,请参阅MVC Config一节中的Interceptors。 您也可以通过单个HandlerMapping实现上的setters直接注册它们。

注意:postHandle对于@ResponseBodyResponseEntity方法不太管用(因为在HandlerAdapterpostHandle之前就已经写入和提交response)。这意味着对response进行任何更改都为时已晚,例如添加额外的header。对于这种场景,你可以实现ResponseBodyAdvice,并将其声明为Controller Advice bean或直接在RequestMappingHandlerAdapter上进行配置。

1.2.7.Exceptions - 异常

如果在请求映射期间发生异常或从请求处理程序handler(如@Controller)抛出异常,DispatcherServlet委托HandlerExceptionResolver bean链来解决异常并提供替代处理,这通常是错误响应。

下表列出了可用的HandlerExceptionResolver实现:

HandlerExceptionResolver描述
SimpleMappingExceptionResolver异常类名称和错误视图名称之间的映射。 用于在浏览器应用程序中呈现错误页面。
DefaultHandlerExceptionResolver解决Spring MVC引发的异常并将它们映射到HTTP状态代码。 另请参阅其他ResponseEntityExceptionHandlerREST API exceptions
ResponseStatusExceptionResolver使用@ResponseStatus注解解决异常,并根据注解中的值将它们映射到HTTP状态代码。
ExceptionHandlerExceptionResolver通过在@Controller@ControllerAdvice类中调用@ExceptionHandler方法来解决异常。 请参阅 @ExceptionHandler methods.
Chain of resolvers - 异常解析器链

你可以通过在Spring配置中声明多个HandlerExceptionResolver bean并根据需要设置它们的顺序属性来形成异常解析链(exception resolver chain)。 order属性越高,异常解析器位置越靠后。

HandlerExceptionResolver的约定指定它可以返回:

  • ModelAndView:指向错误视图的ModelAndView
  • 如果在解析器中已经处理过异常,则返回empty的ModelAndView
  • 如果异常未解决,则返回null,供后续解析器尝试解决;如果异常在最后仍然为处理,它可以冒泡到Servlet容器。

MVC Config 自动为默认的Spring MVC异常,为@ResponseStatus注解修饰的异常,为支持@ExceptionHandler方法 声明了内置的解析器(resolver)。你可以自定义该列表或将其替换。

Container error page - 容器错误页面

如果一个异常未被任何HandlerExceptionResolver解决并因此传播,或者响应状态(response status)设置为错误状态(即4xx,5xx),则Servlet容器可能会在HTML中呈现默认错误页面。要自定义容器的默认错误页面,可以在web.xml中声明错误页面映射:

<error-page>
    <location>/error</location>
</error-page>

鉴于上述情况,当异常冒泡时,或者响应具有错误状态时,Servlet容器在容器内将ERROR分派(dispatch)到配置的URL(例如“/ error”)。然后由DispatcherServlet进行处理,将其映射到一个@Controller,该实现可以通过model返回错误视图名称或呈现JSON响应,如下所示:

@RestController
public class ErrorController {

    @RequestMapping(path = "/error")
    public Map<String, Object> handle(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", request.getAttribute("javax.servlet.error.status_code"));
        map.put("reason", request.getAttribute("javax.servlet.error.message"));
        return map;
    }
}

Servlet API不提供在Java中创建错误页面映射的方法。 但是,您可以同时使用WebApplicationInitializerminimalweb.xml

1.2.8. View Resolution - 视图解析器

Spring MVC定义了ViewResolverView接口,使您可以在浏览器中呈现模型(视图),而无需绑定到特定的视图技术。 ViewResolver提供了视图名称和实际视图之间的映射。View负责在交付给特定视图技术之前准备好处理数据。

下表是ViewResolver的层次结构:

ViewResolver说明
AbstractCachingViewResolverAbstractCachingViewResolver的子类可以缓存它们所解析的视图实例。这种缓存机制提高了某些视图技术的性能。 如果我们不想使用缓存机制,可以将缓存属性设置为false来关闭缓存。此外,如果想在运行时刷新某些视图(例如,在修改FreeMarker模板时),则可以使用removeFromCache(String viewName,Locale loc)方法清除缓存。
XmlViewResolverXmlViewResolverViewResolver接口的实现类,它可以用XML文件配置,配置文件的限定与Springbean文件使用相同的DTD。 默认的配置文件是/WEB-INF/views.xml
ResourceBundleViewResolverResourceBundleViewResolverViewResolver 接口的实现类,它使用ResourceBundle中的 bean 定义,由 bundlebase name指定,对于它应该解析的每个视图,它使用属性[viewname]的值。(class)作为视图类,并将property [viewname] .url的值作为视图url。参考View Technologies
UrlBasedViewResolverViewResolver 接口的简单实现类,在没有明确映射的情况下,该接口起着逻辑视图名称到 URL 的直接解析的作用。 如果逻辑名称以直观的方式与视图资源的名称匹配,则不需要任何映射。
InternalResourceViewResolverUrlBasedViewResolver的便捷子类,支持InternalResourceView(对 ServletJSP 有效)及其子类(如JstlViewTilesView)。你可以使用setViewClass()方法为由此解析器生成的所有视图指定视图类。
FreeMarkerViewResolverUrlBasedViewResolver的便捷子类,支持FreeMarkerView和它们的自定义子类。
ContentNegotiatingViewResolverViewResolver 接口的实现类,可实现基于请求文件名或 Accept 头解析视图。参考 Content negotiation.
Handing - 处理规则

声明多个解析器的bean实例会产生一个视图解析器链(view resolver chain),可以设置order属性来指定排序。优先级属性越高,该视图解析器在链中的位置越靠后(也就是解析顺序靠后)。

根据ViewResolver所遵守的约定:如果ViewResolver无法找到视图(view)会返回null。但是,对于JSP和InternalResourceViewResolver,确定JSP是否存在的唯一方法是通过RequestDispatcher执行分派(dispatch)。因此,必须始终将InternalResourceViewResolver配置为视图解析器链中的最后一个。

配置视图解析器和把ViewResolver 的 bean添加到Spring的配置一样。 MVC ConfigView Resolvers提供了一套专用的配置API,并且还可用于添加无逻辑的View Resolvers,这些View Controller无需控制器逻辑即可用于HTML模板渲染。

Redirecting - 重定向

redirect:视图名称中加前缀redirect则允许执行重定向。UrlBasedViewResolver(和子类)将此识别为需要重定向的指令。视图名称的其余部分是重定向URL。

实际效果与控制器返回一个RedirectView的效果相同,但现在控制器本身可以简单地按逻辑视图名称操作。 一个逻辑视图名称(如redirect:/ myapp / some / resource)将相对于当前的Servlet context上下文重定向,而名称(如redirect:http://myhost.com/some/arbitrary/path)将重定向到绝对URL。

注意,如果控制器方法使用@ResponseStatus进行注解,则注解值对与响应状态(response status)的设置优先于RedirectView的设置。

Forwarding - 转发规则

forward:在逻辑视图名称中加此前缀也能实现转发。拥有forward前缀的视图名称将被UrlBasedViewResolver和子类解析。这样的话会创建一个执行RequestDispatcher.forward()方法的InternalResourceView。因此,对于InternalResourceViewResolverInternalResourceView(对于JSP),此前缀不起作用(因为如果是InternalResourceViewResolverJSP,根据handing中的约定,会由RequestDispatcher执行dispatch),但如果使用其他视图技术,但仍希望强制转发资源被Servlet / JSP引擎所处理,可以使用forward:前缀。注意:这种情况也支持链接多个视图解析器。

Content negotiation

ContentNegotiatingViewResolver不会自行解析视图,而是委托给其他视图解析器,并选择视图,该视图类似于由客户端请求的representation(表示)。该representation(表示)从Acceptheader或查询参数确定,例如:"/path?format=pdf"

ContentNegotiatingViewResolver会选择适当的View来处理请求,通过将请求的media type(s)与ViewResolvers关联的View所支持的media type(s)(也称为Content-Type)进行比较。 具有兼容性的Content-Type视图列表中的第一个视图(view)把representation(表示)返回给客户端。如果ViewResolver链无法提供兼容性视图,则会查看通过DefaultViews属性指定的视图列表。这种选项适用于单例视图,该视图可以呈现当前资源的适当representation(表示),而不管逻辑视图名称如何。什么是兼容性的Content-TypeAccept header可能包含通配符,例如text / *,在这种情况下,其Content-Typetext / xmlView是兼容性匹配。

See View Resolvers under MVC Config for configuration details.

1.2.9.Locale

1.2.10.Themes

1.2.11.Multipart resolver

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 智慧社区背景与挑战 随着城市化的快速发展,社区面临健康、安全、邻里关系和服务质量等多方面的挑战。华为技术有限公司提出智慧社区解决方案,旨在通过先进的数字化技术应对这些问题,提升城市社区的生活质量。 2. 技术推动智慧社区发展 技术进步,特别是数字化、无线化、移动化和物联化,为城市社区的智慧化提供了可能。这些技术的应用不仅提高了社区的运行效率,也增强了居民的便利性和安全性。 3. 智慧社区的核心价值 智慧社区承载了智慧城市的核心价值,通过全面信息化处理,实现对城市各个方面的数字网络化管理、服务与决策功能,从而提升社会服务效率,整合社会服务资源。 4. 多层次、全方位的智慧社区服务 智慧社区通过构建和谐、温情、平安和健康四大社区模块,满足社区居民的多层次需求。这些服务模块包括社区医疗、安全监控、情感沟通和健康监测等。 5. 智慧社区技术框架 智慧社区技术框架强调统一平台的建设,设立数据中心,构建基础网络,并通过分层建设,实现平台能力及应用的可持续成长和扩展。 6. 感知统一平台与服务方案 感知统一平台是智慧社区的关键组成部分,通过统一的RFID身份识别和信息管理,实现社区服务的智能化和便捷化。同时,提供社区内外监控、紧急救助服务和便民服务等。 7. 健康社区的构建 健康社区模块专注于为居民提供健康管理服务,通过整合医疗资源和居民接入,实现远程医疗、慢性病管理和紧急救助等功能,推动医疗模式从治疗向预防转变。 8. 平安社区的安全保障 平安社区通过闭路电视监控、防盗报警和紧急求助等技术,保障社区居民的人身和财产安全,实现社区环境的实时监控和智能分析。 9. 温情社区的情感沟通 温情社区着重于建立社区居民间的情感联系,通过组织社区活动、一键呼叫服务和互帮互助平台,增强邻里间的交流和互助。 10. 和谐社区的资源整合 和谐社区作为社会资源的整合协调者,通过统一接入和身份识别,实现社区信息和服务的便捷获取,提升居民生活质量,促进社区和谐。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值