持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
使用CharacterEncodingFilter
-
SpringMVC底层默认处理响应乱码
-
SpringMVC处理请求乱码步骤
-
注册CharacterEncodingFilter
- 注册CharacterEncodingFilter必须是第一Filter位置
-
为CharacterEncodingFilter中属性encoding赋值
-
为CharacterEncodingFilter中属性forceEncoding/forceRequestEncoding赋值
-
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置编码为UTF-8 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 解决请求与响应乱码 -->
<init-param>
<!-- 调用方法setForceRequestEncoding,这里只是指定request,底层已经处理相应乱码了,可能会出现冲突-->
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
源码解析SpringMVC工作原理
视图解析器对象【ViewResolver】
- 概述:SpringMVC中所有视图解析器对象均实现ViewResolver接口
-
作用:使用ViewResolver将View对象从ModelAndView中解析出来。
-
ThymeleafViewResolver的837行代码
//底层使用反射的方式,newInstance()创建视图对象 final AbstractThymeleafView viewInstance = BeanUtils.instantiateClass(getViewClass());
-
视图对象【View】
-
概述:SpringMVC中所有View对象均实现View接口。
-
作用:视图渲染
- 将数据共享到域中【request、session、application(ServletContext)】
- 跳转路径【转发或重定向】
源码解析:
-
无论方法返回是ModelAndView还是String,最终SpringMVC底层,均会封装为ModelAndView对象【前端控制器调用Controller的入口】
//DispatcherServlet的1061行代码 ModelAndView mv = null; mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); -
SpringMVC解析mv【ModelAndView】
//DispatcherServlet的1078行代码 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); -
ThymeleafView对象中344行代码【SpringMVC底层处理响应乱码】
//computedContentType="text/html;charset=UTF-8" response.setContentType(computedContentType); -
WebEngineContext对象中783行代码【SpringMVC底层将数据默认共享到request域】
this.request.setAttribute(name, value);
\
视图控制器&重定向&加载静态资源
视图控制器
步骤
-
有20+功能,配置后可以解决其他请求路径失效的问题。
- 示例代码:
<!-- 添加视图控制器,为指定URL映射视图-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:view-controller path="/rest" view-name="rest_crud"></mvc:view-controller>
<mvc:view-controller path="/request" view-name="request"></mvc:view-controller>
<mvc:annotation-driven></mvc:annotation-driven>
重定向
重定向页面不可以写在Web-INF下。不使用视图解析器解析资源
语法:return "redirect:/ xxx.html";
发现报错404。此时我们需要将资源加载到服务器。
加载静态资源
-
DefaultServlet加载静态资源到服务器。
- 静态资源:html、css、js
-
tomcat-> conf-> web.xml关键代码如下:
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
问题原因:
- 表层原因:html请求被DispatcherServlet拦截,但是没有找到请求处理的对应方法,但是请求静态资源本来就不需要处理方法。
- 深层次:DispatcherServlet与默认DefaultServlet配置均为/,导致DispatcherServlet中配置将DefaultServlet中配置的/覆盖了。【导致无法加载静态资源】
-
解决方案:
<!-- 解决重定向时的静态资源加载问题 --> <mvc:default-servlet-handler></mvc:default-servlet-handler> <mvc:annotation-driven></mvc:annotation-driven>\