SpringBoot 之 MVC

SpringBoot MVC 和静态资源

首先,我们一定要搞清楚,mvc 配置和 static 配置的联系和区别。 mvc 配置其实就是给 spring mvc 框架用的, 具体来说, 比如 @RequestMapping, 它会返回一个ModelAndView。 我们对这个ModelAndView进行渲染的时候, 需要查找 view, 具体怎么查找呢? 通过mvc 的各种配置。 当然,最终是交给了某个 viewResolver 进行解析。静态资源,其实也是经过了spring mvc,具体来说是ResourceHttpRequestHandler,但ResourceHttpRequestHandler 几乎不需要配置。spring mvc几乎没有提供静态资源的配置项(除了一个静态资源的映射),boot倒是提供了 关于位置和后缀的配置, 具体参见我的boot相关博客。

SpringBoot 中的MVC配置

boot 提供了很多 mvc 配置项,

# SPRING MVC (WebMvcProperties)
spring.mvc.async.request-timeout= # Amount of time (in milliseconds) before asynchronous request handling times out.
spring.mvc.date-format= # Date format to use. For instance `dd/MM/yyyy`.
spring.mvc.dispatch-trace-request=false# Dispatch TRACE requests to the FrameworkServlet doService method.
spring.mvc.dispatch-options-request=true# Dispatch OPTIONS requests to the FrameworkServlet doService method.
spring.mvc.favicon.enabled=true# Enable resolution of favicon.ico.
spring.mvc.formcontent.putfilter.enabled=true # Enable Spring's HttpPutFormContentFilter.
spring.mvc.ignore-default-model-on-redirect=true # If the content of the "default"model should be ignored during redirect scenarios.
spring.mvc.locale= # Locale to use. By default, this locale is overridden by the "Accept-Language"header.
spring.mvc.locale-resolver=accept-header # Define how the locale should be resolved.
spring.mvc.log-resolved-exception=false # Enable warn logging of exceptions resolved by a "HandlerExceptionResolver".
spring.mvc.media-types.*= # Maps file extensions to media types forcontent negotiation.
spring.mvc.message-codes-resolver-format= # Formatting strategy formessage codes. For instance `PREFIX_ERROR_CODE`.
spring.mvc.servlet.load-on-startup=-1# Load on startup priority of the Spring Web Services servlet.
spring.mvc.static-path-pattern=/** # Path pattern used for static resources.
spring.mvc.throw-exception-if-no-handler-found=false # If a "NoHandlerFoundException" should be thrown if no Handler was found to process a request.
spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.

最常用的大概是:

spring.mvc.view.prefix=/somePath/
spring.mvc.view.suffix=.html

这个两个都是对 viewResolver  进行配置用的。这两个值默认都是空, 为空的意思是说,@RequestMapping 返回的是什么, 那么boot 就直接查找那个view, 没有前缀和后缀 。这会产生一种奇怪的情况, 那就是, 比如映射是@RequestMapping("lk")  返回 "aa" 或者"/aa" ( 结果是一样的 ),  如果aa 文件不存在于跟目录,那么就返回 404; 如果存在,不管 aa 文件内容是什么, 由于浏览器不 识别器类型, 于是变成了下载。。

boot 在查找mvc  view 的时候, 是去静态资源目录去查找的,  也就是 spring.resources.static-locations 对应的目录。

如果我们直接反问静态资源, 不管是 spring.mvc.view.prefix 还是 spring.mvc.view.suffix , 还是 其他的 spring.mvc.view 开头的属性, 怎么配置都是没影响的。 但是@RequestMapping返回的view, 却又是在 静态目录进行查找的(非thymeleaf 等视图模板的情况, thymeleaf等是在templates下查找的, 而且 spring.mvc.view.prefix 及 spring.mvc.view.suffix 都是有效的。 这里应该要理清, 不然容易搞混。

再强调一遍, 访问静态资源, 一定要路径完全匹配, 否则就被 boot 认为是访问 动态资源, 比如 mvc 请求!

SpringBoot MVC 和JSP

如果我们希望使用 jsp 做动态资源的渲染, 那么, 我们应该这么配置:

spring.mvc.view.suffix=.jsp

但是呢, 这样做之后,还是不够的。 因为boot 内嵌的 tomcat容器默认不能解析 jsp, 关于 boot 中使用jsp,参见我的另外的博客。 一般来说,最好还是不要再boot 中使用jsp。谁用谁苦自己知道, 我当初就被坑了很久。 官方的说明是这样的:

If possible, JSPs should be avoided. There are several known limitations when using them with embedded servlet containers. —— 尽量不要使用jsp !!

为什么? 因为各种局限:

27.4.5 JSP Limitations
When running a Spring Boot application that uses an embedded servlet container (and is packaged as an executable archive), there are some limitations in the JSP support.

局限1 With Tomcat, it should work if you use war packaging. That is, an executable war works and is also deployable to a standard container (not limited to, but including Tomcat). An executable jar does not work because of a hard-coded file pattern in Tomcat.
局限2  With Jetty, it should work if you use war packaging. That is, an executable war works, and is also deployable to any standard container.
局限3 Undertow does not support JSPs.
局限4 Creating a custom error.jsp page does not override the default view for error handling. Custom error pages should be used instead.

There is a JSP sample so that you can see how to set things up

这么简单的英语我就不翻译了。其实官方也是有提供boot集成jsp示例的,jsp官方的示例是:https://github.com/spring-projects/spring-boot/tree/v2.0.0.M7/spring-boot-samples/spring-boot-sample-web-jsp。 我试过,确实可行(不废话吗,官方的能有啥毛病....) 但是尽管如此,还是很容易踩坑,一不小心就。。

SpringBoot MVC 自动配置是如何生效的?

boot 的mvc 功能大致是通过 WebMvcAutoConfiguration,以及DispatcherServletAutoConfiguration ,EmbeddedServletContainerAutoConfiguration 完成的。它做了很多工作。 多到, 很多时候, 出了问题, 我们搞不清, 只能通过源码来了解。

我们看一下大致有那些 自动配置:

配置了:

DispatcherServlet 这个当然是必须的,在传统项目中,我们可能通过web.xml 来配置,boot 是使用编程方式配置
MultipartResolver 上传解析器
ServletRegistrationBean 用来定制传统的Servlet,一般配合@Bean使用。
OrderedHttpPutFormContentFilter 对method 为put即patch 的form 请求的做一些参数处理
OrderedHiddenHttpMethodFilter 把post请求中_method 参数转换为 请求的method,
ResourceChainResourceHandlerRegistrationCustomizer 资源链,前端资嵌套引用时会用到
WelcomePage 首页,欢迎页面
ResourceResolver 静态资源
RequestMappingHandlerAdapter 
RequestMappingHandlerMapping
Validator
ConfigurableWebBindingInitializer 
ExceptionHandlerExceptionResolver
ContentNegotiationManager
InternalResourceViewResolver
BeanNameViewResolver
ContentNegotiatingViewResolver
LocaleResolver
Formatter<Date>
FaviconConfiguration
ErrorPagexxx

官方说明

它完成了很多的工作。引用 官方 27.1.1 Spring MVC Auto-configuration(https://docs.spring.io/spring-boot/docs/2.0.0.M7/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration)的描述:

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.

The auto-configuration adds the following features on top of Spring’s defaults:

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
Support for serving static resources, including support for WebJars (covered later in this document).
Automatic registration of Converter, GenericConverter, and Formatter beans.
Support for HttpMessageConverters (see below).
Automatic registration of MessageCodesResolver (covered later in this document).
Static index.html support.
Custom Favicon support (covered later in this document).
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

如果你想使用使用spring boot mvc 的特性的同时,想增加一些mvc 的配置,比如拦截器,格式化去,视图控制器等,你可以写一个类继承WebMvcConfigurer,注解 @Configuration,但不要有@EnableWebMvc注解。如果你只是想定制化RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或者ExceptionHandlerExceptionResolver,那么你只要定义一个WebMvcRegistrationsAdapter 实例就ok了

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

如果你想自己控制整个 Spring MVC,你可以写一个自己的配置类,同时注解上@Configuration 和 @EnableWebMvc。

关于OrderedHttpPutFormContentFilter , 大致是这样的:

protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throwsServletException, IOException {if (("PUT".equals(request.getMethod()) || "PATCH".equals(request.getMethod())) && this.isFormContentType(request)) {HttpInputMessage inputMessage= newServletServerHttpRequest(request) {public InputStream getBody() throwsIOException {returnrequest.getInputStream();}};MultiValueMap<String, String> formParameters = this.formConverter.read((Class)null, inputMessage);if (!formParameters.isEmpty()) {HttpServletRequest wrapper= newHttpPutFormContentFilter.HttpPutFormContentRequestWrapper(request, formParameters);filterChain.doFilter(wrapper, response);return;}}filterChain.doFilter(request, response);
}

也就是把put/patch请求的 body解析为请求参数,body 应该是这个格式: aa=11&bb=22; 使用 & 和= 来分隔。就跟我们的get 的querystring是一样的。然后使用 URLDecoder.decode 来解码。 不太懂这里的FormHttpMessageConverter 为什么这么设计,感觉怪怪的。

posted on 2017-12-09 15:22 CanntBelieve 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/FlyAway2013/p/8001767.html

SpringBoot 之 MVC相关推荐

  1. 物流快递系统前、后端+Java语言+SpringBoot项目+MVC三层架构+maven+Mysql+Tomcat+可以用于学习SpringBoot项目入门

    物流快递系统前.后端+Java语言+SpringBoot项目+MVC三层架构+Mysql+Tomcat+可以用于学习SpringBoot项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资 ...

  2. springboot下MVC的MessageConverters和静态资源位置的配置

    文章目录 1. WebMvcConfigurationSupport.WebMvcConfigurer 区别 2. 自定义消息转换器MessageConverters 3. 静态资源 3.1 静态资源 ...

  3. springboot mvc html,完美起航-SpringBoot整合MVC

    2021-03-27 目录: 一 SpringBoot 整合 SpringMVC 二 SpringBoot 基于 SpringMVC 和 Mybatis 的简单案例 一 SpringBoot 整合 S ...

  4. SpringBoot Spring MVC

    一.初始Spring MVC 1.1 什么是Spring MVC 1.Spring MVC是Spring框架的一部分   Spring MVC是一种轻量级的.基于MVC的Web层应用框架.Spring ...

  5. SpringBoot - LogAroundAop MVC请求日志拦截

    代码测试,上线后的调试手段现在很多都喜欢用日志来处理,当我们需要查询某个接口报错的时候,直接看日志,问题描述不清晰, 会发现不知道前端传的什么参数,需要找前端确认,很耗时,所以加了一个请求入参和响应的 ...

  6. B站云E办Vue+SpringBoot前后端分离项目——MVC三层架构搭建后台项目

    本项目来源B站云E办,笔记整理了项目搭建的过程和涉及的知识点.对于学习来说,不是复制粘贴代码即可,要知其然知其所以然.希望我的笔记能为大家提供思路,也欢迎各位伙伴的指正. 项目前端学习笔记目录 B站云 ...

  7. SpringBoot微服务架构下的MVC模型总结

    SpringBoot微服务架构下的MVC模型产生的原因: 微服务概念改变着软件开发领域,传统的开源框架结构开发,由于其繁琐的配置流程 , 复杂的设置行为,为项目的开发增加了繁重的工作量,微服务致力于解 ...

  8. 框架:spring、springmvc、springboot

    先来说说spring.springmvc.springboot的关系. spring boot只是一个配置工具,整合工具,辅助工具. springmvc是框架,项目中实际运行的代码 Spring 框架 ...

  9. 【springboot】之 解析@EnableWebMvc 、WebMvcConfigurationSupport和WebMvcConfigurationAdapter

    springboot默认格式化日期只需要在application文件中配置 spring.jackson.date-format= yyyy-MM-dd HH:mm:ss spring.jackson ...

最新文章

  1. wifi linux 驱动分析,Linux 下wifi 驱动开发(二)—— WiFi模块浅析
  2. react+redux+generation-modation脚手架搭建一个todolist
  3. 使用ueditor实现多图片上传案例——实体类(Shopping.java)
  4. mybatis_user_guide(4) Mapper XML 文件
  5. mysql如何定位耗时较长的sql_Mysql实例mysql优化之定位效率较低的SQL
  6. [转载] 如何使用Python 实现秒表功能?
  7. Webapck Vue多页面商城模板
  8. 牵引变压器短路阻抗定义及相关参数计算
  9. 最新互联网架构师视频教程+源码20G
  10. apk软件去广告 傻瓜教程
  11. Kubernetes单机开发环境部署记录
  12. Google与百度、搜狗合作,共同推进移动网络发展
  13. Renix签名字段详解——网络测试仪实操
  14. 拼多多显示服务器有点问题,拼多多为什么登录不上 登录不上解决方法
  15. OpenGL学习之路17---- 镜面反射光
  16. 电脑更改开机密码和用户名
  17. 在IE浏览器中实现网页自动翻译
  18. 智能工厂到底是什么?
  19. DNW for CentOS7
  20. 测试方案模板(性能测试为例子)

热门文章

  1. ultraMaskedEdit使用心得
  2. 【c++】【转】如何只在heap上创建对象,如何只在stack上建立对象?
  3. 安卓开发8-WebView支持文件上传
  4. LoadRunner系统架构简介与运行原理
  5. C语言程序设计代码树,校门外的树 (C语言代码)
  6. mysql 非等值条件 索引_mysql 索引学习--多条件等值查询,顺序不同也能应用联合索引啦...
  7. 手绘线条一直画不直_我学素描,线条画不直怎么办啊?
  8. 4.QML动画——概念、动画应用方式和动画的缓动曲线
  9. try/catch的用法
  10. ubuntu 能解析域名但ping不通_域名解析设置方法