Servlet请求转发至html页面中文乱码问题与分析
起因
在编写servlet
代码的时候,练习重定向和请求转发,发现重定向至html
页面时,页面显示中文正常,使用请求转发至html
页面时,显示中文乱码,两个servlet
都在doGet()
方法内首先使用了resp.setCharacterEncoding("UTF-8");
设置编码为UTF-8
。
核心代码
各部分核心代码如下:
重定向repRedirect
代码:
请求转发repForward.java
代码:
跳转的html页面代码
welcome.html
:
访问效果
访问重定向页面
访问请求转发页面
可以看出请求转发出现了乱码
我们再故意输错密码,测试一下请求转发失败的页面fail.html
同样乱码
解决方法(1)
网上已经有人给出了解决方法,即将请求转发跳转的html
编码设置为GBK
,如下
重新访问请求转发页面
此时乱码恢复正常
fail.html
页面并没有修改为GBK
,我们访问它试试,进行对照比较
依旧乱码,可以看出是设置GBK
生效
原因分析
虽然这样设置能够让页面的乱码正常,但是我们实际上是在servlet
里面设置了UTF-8
编码,为什么页面上还需要改为GBK
,而为什么请求转发和重定向都设置了UTF-8
但只有请求转发的页面显示乱码了
在这篇博文中提到
因此,我认为一个HTML文件在集成开发创建时是UTF-8的格式,这个格式在IDE上应该可以设置,但在打开时是更具默认编码格式打开的(即ANSI),因此会产生乱码
而在我们的讨论+猜测下,请求转发的过程类似于
图中的GBK
指的是servlet默认读取文件的编码方式,不同地区的电脑可能默认不一样
在另一篇博文对请求转发详细流程的介绍中也提到:
forward() 方法的处理流程:
● 清空用于存放响应正文(响应体)数据的缓冲区。
● 如果目标组件为Servlet 或JSP,就调用它们的service() 方法,把该方法产生的响应结果发送到客户端,如果目标组件为文件系统中的静态 html 文档,就读去文档中的数据并把它发送到客户端。
也就是说,请求转发是有一个读文档数据的过程,侧面论证了图示
读文档数据涉及到了文档原来的编码和读取文件的编码方式,分析可得,出现乱码的原因是,文档本身的编码是UTF-8
,但servlet读取时是使用默认编码方式GBK
读取的。
而我们在servlet中设置编码的过程,也就是图中的第二部分,所以不管我们用什么样的方式设置UTF-8
,都只会让只能使用GBK
解析的页面乱码
当然这一部分还是猜测,所以我们用另外两种方法来验证我们的观点
论证1
不管编码解码的结果如何,我们想要传递的数据字节流是不变的,它不会因为乱码字符就从登陆成功变成登陆失败,换一句话说,不管用中文还是英文表达同一件事情,其内核都是表达的这件事,并不会因为使用的语言而改变
既然文档本身的编码是UTF-8
,servlet读取方式为GBK
,我们把文档本身编码修改为GBK
,如果上面的推断是正确的,这样做应该就能够让乱码正常
流程为:
GBK -> GBK -> 字符流 -> UTF-8 ->UTF-8页面显示
打开VScode
,方便转换编码
可以看到文件此时保存的编码为UTF-8
我们修改其为GBK
,点击通过编码保存
设置成GBK
可以见到此时文件保存编码修改为了 GBK
这个时候再启动servlet
请求转发
访问 http://127.0.0.1:8080/repForward?username=admin&password=123456
显示正常
侧面反映了我们思考的过程是正确的
论证2
配置XML
文件
意思是,任何以html
结尾的URL请求的资源,都以UTF-8
格式打开,这里也就是修改servlet
的读取文件编码方式,此时将welcome.html
文件的编码修改回UTF-8
重启服务,访问请求转发页面
此时访问的页面编码依旧没有乱码,说明jsp-config
起了作用,同时确实是因为servlrt
默认读取html
文件的编码方式为GBK
为了验证真的是jsp-config
的作用,将其删除再试一次
删除后访问乱码
证明确实servlet
默认读取html
文件编码方式为GBK
,这个默认方式不同的地区应该是不同的,例如美国应该是ASCII
总结
两个论证中的方法也都能解决请求转发至html
页面乱码的问题
乱码出现的原因是文件本身编码和servlet
默认读取文件编码方式不一样而导致的
至于为什么重定向的页面显示中文是正常的,我们认为是请求转发和重定向这两个功能的实现在servlet
中不一样,比如请求转发是需要读取转发的html
文件,重定向是让用户自己重新去访问html
页面,缺少了默认读取的部分,具体的实现区别需要看servlet
的源代码才能知道
参考链接
- https://blog.csdn.net/qq_27368993/article/details/83616090
- https://blog.csdn.net/qq_26164609/article/details/102826376
END
建了一个微信的安全交流群,欢迎添加我微信备注进群
,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注 😃
__EOF__

本文链接:https://www.cnblogs.com/Cl0ud/p/15322455.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!