前端把表单改成 POST 之后,后端取不到值了,打印出来是 null。代码看着没问题,就 request.getParameter 这一行。查了半天才发现,表单的 enctype 写成了 multipart/form-data。
getParameter 的规则不复杂:它只在两种地方找值。GET 请求的查询串,也就是问号后面那一段;POST 请求且 Content-Type 是 application/x-www-form-urlencoded 时的请求体。这两个来源都匹配不上,就返回 null。multipart 表单必须用 getPart 或者框架自带的上传组件,getParameter 拿不到。
名字大小写和空值的坑
- 大小写敏感:参数名 userName 和 username 是两个不同的键,前端传错一个字母就是 null
- null 和空串:参数存在但没填,返回空串;参数根本不存在,返回 null。判空别只写 equals 空字符串
- 同名多值:复选框会传多个同名参数,得用 getParameterValues 拿数组,只调 getParameter 只会拿到第一个
- 数组下标:ids[0]=1 这种写法不是标准,别指望能取到
中文乱码先看编码设置
Tomcat 8 以后默认 URI 编码是 UTF-8,一般不用管。老版本或者容器配置改过,需要 request.setCharacterEncoding 设成 UTF-8,而且这句必须放在第一次调用 getParameter 之前。因为一旦读过参数,容器已经把流解析完了,再设编码不生效。
POST 的编码看请求体,GET 的编码在 Tomcat 里由 Connector 的 URIEncoding 决定,server.xml 里可以配。两者不是同一个开关,调错地方会白忙一场。用 Spring Boot 的话,server.tomcat.uri-encoding 管的是后者。
String name = request.getParameter(USER_NAME); if(name == null || name.trim().isEmpty()){ name = DEFAULT_NAME; }还有一点,Spring MVC 里 RequestParam 默认 required=true,缺参数直接抛 400,比返回 null 更容易排查。要不要强制必填,看接口契约,别为了省事全设成 false,最后在业务层到处判空,代码越写越乱。
排查这类问题有个笨办法但很有效:在过滤器里把请求方法、Content-Type、参数 Map 一起打出来,一眼就能看出值到底有没有进来。