怎么修改网站源文件/友情链接英文
SpringMVC的中文乱码问题其实已经不是什么问题了,无非就是配置编码方式->解决问题。
但是由于SpringMVC可以通过:xml方式配置、Servlet3.0方式配置,以及是否使用@EnableWebMvc等,不同配置方式下,解决中文乱码问题的方案有所不同。
xml配置的方式
xml配置方式的解决方案最简单:
<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><init-param><param-name>forceRequestEncoding</param-name><param-value>true</param-value></init-param><init-param><param-name>forceResponseEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
在web.xml文件中加编码过滤器,并强制过滤器对Request和Response都生效,可以解决request请求、以及response返回参数中的中文乱码问题。
但是返回体,也就是response body中的中文乱码问题,以上过滤器方案无法解决。
Response body中的中文乱码问题需要在spring MVC中增加以下配置:
<mvc:annotation-driven ><!--设置响应输出字符集--><mvc:message-converters><bean class="org.springframework.http.converter.StringHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=utf-8</value></list></property></bean></mvc:message-converters></mvc:annotation-driven>
前面一篇文章[Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven] 分析过<mvc:annotation-driven />标签的解析过程,该标签在创建RequestMappingHandlerAdapter的过程中,会读取到xml文件中messageConverters的定义并设置到RequestMappingHandlerAdapter对象的messageConverters属性中并最终在DispatcherServlet处理请求的过程中生效。
Servlet3.0配置
Servlet3.0的配置方式,是指通过WebApplicationInitializer接口完成SpringMVC配置的方式。
可以通过接口方法getServletFilters增加编码过滤器:
public class MvcInitializerextends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {
// return null;return new Class[] {RootConfiguration.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {
// return null;return new Class[] {MvcConfiguration.class,CommonConfiguration.class};}@Overrideprotected String[] getServletMappings() {return new String[] {"/"};}@Overrideprotected Filter[] getServletFilters() {
// ShallowEtagHeaderFilter shallowEtagHeaderFilter = new ShallowEtagHeaderFilter();
// shallowEtagHeaderFilter.setWriteWeakETag(true);CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();characterEncodingFilter.setEncoding("utf-8");characterEncodingFilter.setForceEncoding(true);return new Filter[]{characterEncodingFilter};}
}
以上方式增加过滤器后,可以解决request和response请求及返回参数中的中文编码问题。
但是无法解决response body的中文乱码问题。
由于WebApplicationInitializer接口并没有提供任何关于messageConverters的接口,看了很多遍源码也并没有找到可以配置的地方,网上也没有找到相关解决方案…所以解决这个问题还是费了很多周折。
由于我们已经知道,response body的中文乱码问题最终是通过RequestMappingHandlerAdapter对象的messageConverters解决的,所以还是想通过定制化RequestMappingHandlerAdapter的初始化过程、设置其messageConverters的方式解决问题。
如果没有定制化处理的话,DispatcherServlet在初始化的过程中是在initStrategies方法中创建DispatcherServlet.properties文件中默认的RequestMappingHandlerAdapter,是通过反射机制直接new出来的,最终会调用到RequestMappingHandlerAdapter的默认构造器:
public RequestMappingHandlerAdapter() {this.messageConverters = new ArrayList<>(4);this.messageConverters.add(new ByteArrayHttpMessageConverter());this.messageConverters.add(new StringHttpMessageConverter());try {this.messageConverters.add(new SourceHttpMessageConverter<>());}catch (Error err) {// Ignore when no TransformerFactory implementation is available}this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());}
默认构造器会直接new一个StringHttpMessageConverter()加进来,不修改的话StringHttpMessageConverter的默认字符集是ISO_8859_1,一定会出现中文乱码问题:
public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
所以我们必须找到某种方式可以定制化RequestMappingHandlerAdapter的初始化过程。
继续分析源码:
private void initHandlerAdapters(ApplicationContext context) {this.handlerAdapters = null;if (this.detectAllHandlerAdapters) {// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.Map<String, HandlerAdapter> matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);if (!matchingBeans.isEmpty()) {this.handlerAdapters = new ArrayList<>(matchingBeans.values());// We keep HandlerAdapters in sorted order.AnnotationAwareOrderComparator.sort(this.handlerAdapters);}}else {try {HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);this.handlerAdapters = Collections.singletonList(ha);}catch (NoSuchBeanDefinitionException ex) {// Ignore, we'll add a default HandlerAdapter later.}}// Ensure we have at least some HandlerAdapters, by registering// default HandlerAdapters if no other adapters are found.if (this.handlerAdapters == null) {this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);if (logger.isTraceEnabled()) {logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +"': using default strategies from DispatcherServlet.properties");}}}
发现initHandlerAdapters方法首先会从Spring容器中获取HandlerAdapter!
我们是否有办法定制一个HandlerAdapter、加入到Spring容器中?Spring当然给我们提供了这种机会,回想一下@Configuration+@Bean注解,是否就可以解决?
在MvcConfig文件中增加如下代码:
@Configuration
@ComponentScan({"org.example.controller"})
public class MvcConfiguration {@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setPrefix("/WEB-INF/pages/");viewResolver.setSuffix(".jsp");return viewResolver;}//定制RequestMappingHandlerAdapter@Beanpublic RequestMappingHandlerAdapter handlerAdapter(){RequestMappingHandlerAdapter handlerAdapter = new RequestMappingHandlerAdapter();List<HttpMessageConverter<?>> messageConverters;messageConverters = new ArrayList<>(4);messageConverters.add(new ByteArrayHttpMessageConverter());StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));messageConverters.add(stringHttpMessageConverter);try {messageConverters.add(new SourceHttpMessageConverter<>());}catch (Error err) {// Ignore when no TransformerFactory implementation is available}messageConverters.add(new AllEncompassingFormHttpMessageConverter());handlerAdapter.setMessageConverters(messageConverters);return handlerAdapter;}
参考RequestMappingHandlerAdapter默认构造器的代码,修改其中StringHttpMessageConverter的创建过程、设置其默认字符集为UTF-8…验证后发现,问题已解决!
使用@EnableWebMvc
由于@EnableWebMvc是必须和@configuration配合使用的,所以,一定会存在配置类。这种情况下,配置类实现WebMvcConfigurer、通过扩展extendMessageConverters方法解决:
@Configuration
@EnableWebMvc
@ComponentScan({"org.example.controller"})
public class MvcConfiguration implements WebMvcConfigurer{public MvcConfiguration(){System.out.println("mvc configuration constructor...");}
// 通过@EnableWebMVC配置的时候起作用,@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {for(HttpMessageConverter httpMessageConverter:converters){if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));}}}}
上一篇 Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven
相关文章:

Spring MVC 十一:中文乱码
SpringMVC的中文乱码问题其实已经不是什么问题了,无非就是配置编码方式->解决问题。 但是由于SpringMVC可以通过:xml方式配置、Servlet3.0方式配置,以及是否使用EnableWebMvc等,不同配置方式下,解决中文乱码问题的…...

Excel恢复科学技术法显示的数据
Excel中输入位数较大的数据时,软件会自动使用科学计数法显示。很多时候并不需要这样的计数格式,所以需要把它转变为普通的数字格式 操作方法 选中单元格/列/行》右键》设置单元格式 在打开的窗口中,切换到“数字”选项卡,点击“自…...

springboot 志同道合交友网站演示
springboot 志同道合交友网站演示 liu1113625581...

如何理解BFC、开启BFC、BFC解决哪些问题
1.BFC 概念 BFC 英文名为 Block Formatting Context (块级格式化上下文) 具体可查看 MDN 2.BFC的作用 元素开启BFC后,子元素不会发生margin塌陷问题元素开启BFC后,子元素浮动,元素不发生高度塌陷元素开启BFC后,该元素不被其他元…...

3D包容盒子
原理简述 包围体(包容盒)是一个简单的几何空间,里面包含着复杂形状的物体。为物体添加包围体的目的是快速的进行碰撞检测或者进行精确的碰撞检测之前进行过滤(即当包围体碰撞,才进行精确碰撞检测和处理)。包…...

用 Three.js 创建一个酷炫且真实的地球
接下来我会分步骤讲解,在线示例在数字孪生平台。 先添加一个球体 我们用threejs中的SphereGeometry来创建球体,给他贴一张地球纹理。 let earthGeo new THREE.SphereGeometry(10, 64, 64) let earthMat new THREE.MeshStandardMaterial({map: albed…...

【数据结构】线性表与顺序表
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 线性表与顺序表 1. 线性表2. 顺序表2.1 …...

ChatGPT
chatgpt使用地址 https://mycaht.top/#/chat 申请内测免费key https://github.com/chatanywhere/GPT_API_free 设置 接口地址设置改成 https://api.chatanywhere.com.cnAPI Key设置成申请出来的免费key 开始聊天...

矿区井下智慧用电安全监测解决方案
一、背景 矿区井下作业具有复杂的环境和较高的危险性,对于用电安全的要求尤为严格。传统的管理模式和监测方法往往无法实时、准确地掌握井下用电情况,对安全隐患的排查与预防存在一定局限性。因此,引入智慧用电安全监测解决方案ÿ…...

网站列表页加密:三次请求后返回内容多\r
一、抓包第一次请求 url aHR0cDovL2N5eHcuY24vQ29sdW1uLmFzcHg/Y29saWQ9MTA抓包,需要清理浏览器cookie,或者无痕模式打开网址,否则返回的包不全,依照下图中的第一个包进行requests请求 第一次请求后返回 <!DOCTYPE html>…...

12.JVM
一.JVM类加载机制:把类从硬盘文件加载到内存中 1.java文件,编写时是一个.java文件,编译后现成一个.class的字节码文件,运行的时候,JVM就会读取.class文件,放到内存中,并且构造类对象. 2.类加载流程: a.加载:找到.class文件,打开文件,读取内容,尝试解析文件内容. b.验证:检查…...

关于网络协议的若干问题(四)
1、QUIC 是一个精巧的协议,它有哪些特性? 答:QUIC 还有其他特性,一个是快速建立连接。另一个是拥塞控制,QUIC 协议当前默认使用了 TCP 协议的 CUBIC(拥塞控制算法)。 CUBIC 进行了不同的设计&…...

opencv图像卷积操作和常用的图像滤波函数
文章目录 opencv图像卷积操作原理,opencv中常用的图像滤波函数一、图像卷积操作原理:1、卷积操作原理图: 二、opencv常用的图像滤波函数:这些函数的主要作用是对图像进行平滑处理或去除噪声(核心目的是减少图像中的噪声࿰…...

习题1. 31
话不多说 先上代码 (defn product [ term a nxt b](defn iter [a result](if (> a b)1 (* (term a) (iter (nxt a) result))))(iter a 1)) 跟习题1.30比较起来,就是两个地方不同 乘法不能乘0 必须是1。难度来讲,跟1.30难度是一样的。增加了迭代过…...

见微知著:从企业售后技术支持看云计算发展
作者:余凯 售后业务中的细微变化 作为阿里云企业容器技术支持的一员,每天会面对全球各地企业级客户提出的关于容器的各种问题,通过这几年的技术支持的经历,逐步发现容器问题客户的一些惯性,哪些是重度用户࿰…...

C++笔记之如何给 `const char*` 类型变量赋值
C笔记之如何给 const char* 类型变量赋值 code review! 文章目录 C笔记之如何给 const char* 类型变量赋值1.在C中,如果你要给一个 const char* 变量赋值,你通常有几种方法来做这件事,具体取决于你的需求。下面是一些常见的方法:…...

9.Linear Maps
线性映射 线性映射是将向量作为输入并产生一些新向量作为输出的转换。 从坐标定义开始(数组),再到2,3,并展示它们是如何关联的 线性映射的坐标表示最终是矩阵, 1.坐标定义(数组) 列向量是向量的坐标表示…...

大数据Doris(十):添加BE步骤
文章目录 添加BE步骤 一、使用mysql连接 二、添加be...

Vue2 +Element UI 表格行合并
如果相邻数据是一致的,则单元格的行合并,指定需要合并的列,下面我是指定合并了分类和类型这两列。 先看效果 Element UI为我们的<el-table>提供了一个属性span-method:合并行或列的计算方法 下面是一个示例: html部分 - 主要是在表上指…...

SuperEdge易学易用系列-一键搭建SuperEdge集群
条件说明: 系统 公网IP 内网IP 服务器所在地 K8S版本 Centos7.9 114.116.101.254 192.168.0.245 北京 v1.22.6 Centos7.9 119.8.1.96 192.168.0.83 香港 v1.22.6 Ubuntu22 94.74.108.152 192.168.0.154 纽约 v1.22.6 1. 开始部署 1.1 两条指令从零搭建一个边缘集…...

农场养殖农产品商城小程序搭建
鸡鸭羊牛鱼养殖用户不少,其规模也有大有小,尤其对一些生态养殖企业,其产品需求度更高,同时他们也有实际的销售需求。 由于具备较为稳定的货源,因此大规模多规格销售属性很足。 通过【雨科】平台搭建农场养殖商城&…...

大语言模型之十七-QA-LoRA
由于基座模型通常需要海量的数据和算力内存,这一巨大的成本往往只有巨头公司会投入,所以一些优秀的大语言模型要么是大公司开源的,要么是背后有大公司身影公司开源的,如何从优秀的开源基座模型针对特定场景fine-tune模型具有广大的…...

UML组件图综合指南:设计清晰、可维护的软件系统
介绍: UML(Unified Modeling Language)组件图是软件系统设计中的重要工具,用于描绘系统的物理结构和组件之间的关系。在软件工程中,通过创建清晰的组件图,团队能够更好地理解系统的模块化结构和组织关系&a…...

深入浅出ThreadPoolExecutor(一)
文章目录 线程池简诉ThreadPoolExecutor详解ThreadPoolExecutor参数详解创建线程池的工具类Executors 线程池简诉 针对各种池子,比如 连接池:用于管理和重复使用数据库连接,避免频繁创建和销毁数据库连接带来的性能开销。对象池:用于管理和重复使用对象…...

网站的常见攻击与防护方法
在互联网时代,几乎每个网站都存在着潜在的安全威胁。这些威胁可能来自人为失误,也可能源自网络犯罪团伙所发起的复杂攻击。无论攻击的本质如何,网络攻击者的主要动机通常是谋求经济利益。这意味着无论您经营的是电子商务项目还是小型商业网站…...

网络工程师知识点3
41、各个路由协议,在华为设备中的优先级? 直连路由 0 OSPF 10 静态 60 42、OSPF:开放式最短路径优先路由协议,使用SPF算法发现和计算路由 OSPF的优点: 1、收敛速度快,无路由自环,适用于大型网络…...

mongoDB 性能优化
文章目录 前言mongoDB 性能优化1. explain方法来查看查询的执行计划2. 查看mongoDB 集合的索引3. mongoDB 怎么添加索引4. 升序索引与降序索引是什么意思 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易…...

10月13日,每日信息差
今天是2023年10月13日,以下是为您准备的13条信息差 第一、欧盟投资4.5亿欧元在法国建设电池超级工厂。欧洲投资银行是欧盟的贷款机构,也是世界上最大的跨国银行之一 第二、北京银行推出数字人民币智能合约平台 数字人民币预付资金管理产品在商超场景…...

Spring Boot 中的 Redis 数据操作配置和使用
Spring Boot 中的 Redis 数据操作配置和使用 Redis(Remote Dictionary Server)是一种高性能的开源内存数据库,用于缓存、消息队列、会话管理和数据存储。在Spring Boot应用程序中,Redis被广泛用于各种用例,包括缓存、…...

rust宏
宏看起来和函数很像,只不过名称末尾有一个感叹号 ! 。 宏并不产生函数调用,而是展开成源码,并和程序的其余部分一起被编译。 Rust宏和C不同,Rust的宏会展开为抽象语法树(AST,abstract syntax treeÿ…...