Spring如何将表单输入框值传递给@RequestMapping的@PathVariable参数
问题根因
出现路径匹配失败、参数为null的核心原因有两个:
- JSP中form的action路径写法逻辑错误:你写的
$mobilePhoneNumber是无效占位符,就算修正为标准EL表达式${mobilePhoneNumber}也无法获取用户输入值——EL表达式是服务端渲染JSP时读取后端域属性生成静态页面内容,用户在输入框填写的内容是浏览器端提交时才产生的,服务端渲染阶段根本拿不到这个值,最终生成的HTML里action路径最后一段始终是空的。 - 原生HTML表单默认提交逻辑不会自动替换路径占位符:POST表单默认会把输入框内容封装到form-data请求体或URL查询参数中,不会自动拼接到URL路径段上,所以最终提交的请求地址是
/api/v1/checkPhoneNumber/,最后一段没有值,匹配不到你定义的带{mobilePhoneNumber}路径变量的接口,就会抛出No mapping found的警告。
解决方案
两种实现方式二选一即可,没有特殊路径参数要求优先选第二种,实现更简单。
方案一:保留@PathVariable传参,前端提交前动态拼接路径
需要加一段简单的JS逻辑,在用户点击提交、请求发出去之前,把输入框的手机号拼到请求路径末尾,再提交表单。
修正后的JSP代码:
<form id="insBasicForm" name="insBasicForm" action="${pageContext.request.contextPath}/api/v1/checkPhoneNumber/" method="POST"> <input type="text" id="mobilePhoneNumber" name="mobilePhoneNumber" maxlength="10" title="" placeholder="Telephone Number (Mobile- 10 Digits)" class="w100p" /> <input type="submit" name="" value="Check CCP" class="btn"> </form> <script> const form = document.getElementById('insBasicForm'); form.addEventListener('submit', function(e) { e.preventDefault(); const phoneInput = document.getElementById('mobilePhoneNumber'); const phone = phoneInput.value.trim(); if (!phone) { alert('请输入10位手机号'); phoneInput.focus(); return false; } // 拼接带手机号的完整路径 form.action = form.action + encodeURIComponent(phone); form.submit(); }) </script>
同时修正你Controller层的代码笔误和逻辑缺失:
- 去掉多余的
@RequestParam Map<String, Object> params参数,路径变量不会封装到RequestParam中,多余参数容易引发绑定错误 - 修正catch块的变量笔误(你写的
essage少了首字母m,捕获的异常对象是exception不是e) - 补全RestTemplate发送请求的逻辑,你之前只组装了JSON对象,没有实际发起请求
修正后的Controller代码片段:
@RequestMapping("/api/v1/checkPhoneNumber/{mobilePhoneNumber}") @ResponseBody public ResponseEntity<ReturnMessage> checkCCPHistoryCustomerPoint( @PathVariable("mobilePhoneNumber") String mobilePhoneNumber, ModelMap model) throws Exception { ReturnMessage message = new ReturnMessage(); RestTemplate restTemplate = new RestTemplate(); String thirdPartyUrl = "https://localhost:8080/VR2_REQUEST"; String token = AppConstants.TOKEN; JSONObject jsonObject = new JSONObject(); try { // 组装请求参数,mobilePhoneNumber直接取路径变量绑定的值 jsonObject.put("sessionKey", "2022111723"); jsonObject.put("fiCode", "B100000022"); jsonObject.put("code", "0011524"); jsonObject.put("appNumber", "APPL000000000000999"); jsonObject.put("customerNumber", "12345678"); jsonObject.put("mobilePhoneNumber", mobilePhoneNumber); // 补全请求发送逻辑 HttpHeaders headers = new HttpHeaders(); headers.setBearerAuth(token); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), headers); ResponseEntity<String> thirdPartyResp = restTemplate.postForEntity(thirdPartyUrl, request, String.class); // 这里写你自己的第三方响应解析逻辑 message.setSuccess(true); message.setData(thirdPartyResp.getBody()); } catch (HttpClientErrorException exception) { message.setSuccess(false); message.setMessage(exception.toString()); exception.printStackTrace(); return ResponseEntity.ok(message); } return ResponseEntity.ok(message); }
方案二:改用@RequestParam接收参数(推荐)
如果没有强制要求必须把手机号放到URL路径段里,直接用表单默认的参数传递逻辑即可,不需要写额外JS,实现更简单。
只需要改两处:
- 修改JSP中form的action地址,去掉末尾的占位符:
<form id="insBasicForm" name="insBasicForm" action="${pageContext.request.contextPath}/api/v1/checkPhoneNumber" method="POST"> <input type="text" id="mobilePhoneNumber" name="mobilePhoneNumber" maxlength="10" title="" placeholder="Telephone Number (Mobile- 10 Digits)" class="w100p" /> <input type="submit" name="" value="Check CCP" class="btn"> </form>
- 修改Controller的接口路径,把@PathVariable改成@RequestParam接收参数:
// 路径去掉末尾的/{mobilePhoneNumber} @RequestMapping("/api/v1/checkPhoneNumber") @ResponseBody public ResponseEntity<ReturnMessage> checkCCPHistoryCustomerPoint( // 改用@RequestParam接收表单提交的手机号参数 @RequestParam("mobilePhoneNumber") String mobilePhoneNumber, ModelMap model) throws Exception { // 内部业务逻辑和方案一的完全一致,不需要改动 }
内容的提问来源于stack exchange,提问作者Khanh Luong Van
相关产品推荐
相关产品推荐

