springboot使用undertow作为web容器而引发的中文乱码问题

本文详细分析了在SpringBoot应用中使用Undertow作为Web容器时,由于请求处理过程中的字符编码问题导致中文乱码的成因。在Form表单提交时,由于Undertow容器的特殊处理,使得`request.getCharacterEncoding()`返回null,从而在重定向时未正确使用UTF-8编码。通过跟踪源码,发现`HttpServletRequestImpl`的`parseFormData()`方法导致`readStarted`为true,使得`request.setCharacterEncoding()`失效。为解决此问题,提出了创建一个Web过滤器,采用装饰器模式覆盖`request.getCharacterEncoding()`的方法,当其返回为空时默认返回UTF-8,从而成功解决了乱码问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 先说一下出现这种情况的场景。该场景在使用jetty,tomcat作为容器时是可以正常运行的。首先是表单提交。

<form id="submitForm" action="${base}/test/aa.html" method="post">
            <input type="hidden" name="userSource" value="admin"/>
            <input type="hidden" id="hid_modulus" name="modulus" value="$!{modulus}"/>
 </form> 

 springmvc控制器代码如下:

@RequestMapping("test")
@Controller
public class TestController {

    @RequestMapping("aa.html")
    public String aa(Model model, RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("a","李四");
        return  "redirect:bb.html";
    }

    @RequestMapping("bb.html")
    public String bb(Model model, HttpServletRequest request) {
        String a=request.getParameter("a");
        return "login";
    }
}

 aa方法做了一次重定向,重定向时传参是中文,到进入bb方法时,获取到的string a则为乱码。

查看项目已使用了spring提供的字符集设置过滤器CharacterEncodingFilter。强制设置字符集为utf-8。却依然出现乱码问题。

     没办法,只能查看springmvc的源码。跟踪源码后发现,在RedirectView类的createTargetUrl方法里,会去为重定向拼装url字符串:

protected final String createTargetUrl(Map<String, Object> model, HttpServletRequest request)
			throws UnsupportedEncodingException {

		// Prepare target URL.
		StringBuilder targetUrl = new StringBuilder();
		if (this.contextRelative && getUrl().startsWith("/")) {
			// Do not apply context path to relative URLs.
			targetUrl.append(request.getContextPath());
		}
		targetUrl.append(getUrl());

		String enc = this.encodingScheme;
		if (enc == null) {
			enc = request.getCharacterEncoding();
		}
		if (enc == null) {
			enc = WebUtils.DEFAULT_CHARACTER_ENCODING;
		}

		if (this.expandUriTemplateVariables && StringUtils.hasText(targetUrl)) {
			Map<String, String> variables =
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值