一、 场景铺垫:双十一凌晨的"订单哨兵"
想象一下:现在是 2026 年双十一凌晨一点 。你面前的监控大屏上,全国各地的订单数据正疯狂跳动 。作为后端开发,你需要实现一个极简的微服务,瞬间聚合两个区域的实时订单增量并反馈给前台看板 。虽然业务逻辑是简单的加法,但在高并发的生产环境下,每一行注解的选择都关乎系统的健壮性 。
二、 技术还原:构建你的第一个"聚合器"
(一) 路由映射:建立我们的"通讯基站"
在 Spring MVC 中,建立连接只需通过注解声明路由映射 。
-
@RestController :这是
@Controller和@ResponseBody的结合体 。它告知 Spring 该类由容器管理,且返回的是纯数据(非视图页面),非常适合前后端分离的场景 。 -
@RequestMapping :它定义了接口的 URL 路径 。当我们在类上标注
/calc,方法上标注/sum时,完整的访问路径即为/calc/sum。
(二) 前端投递:calc.html 的表单逻辑
前端通过标准的 form 表单进行数据投递 。
-
接口约定 :表单的
action需对应后端的请求路径/calc/sum。 -
参数匹配 :
<input>标签的name属性(如num1和num2)必须与后端方法的形参名严格一致,Spring 才能自动完成参数绑定 。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="calc/sum" method="post">
<h1>计算器</h1>
数字1:<input name="num1" type="text"><br>
数字2:<input name="num2" type="text"><br>
<input type="submit" value=" 点击相加 ">
</form></body>
</html>
注意要把包含上述代码的html文件放置到 /resource/static 这个目录下
简单的前端页面已搭建完成,此时如果直接访问,在前端页面中尝试计算的话只会出现404not found提示,这是因为我们还未赋予其处理数据的能力,下面来实现一个对应的后端接口
(三) 核心逻辑:CalcController 的代码实现
后端接收参数并执行求和,最终返回一个 HTML 代码片段 。
java
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2) { // 接收求和参数 [cite: 715]
Integer sum = num1 + num2;
// 返回 <h1> 标签包裹的结果,浏览器会自动解析
return "<h1>计算机计算结果: " + sum + "</h1>";
}
}

如果不想要把传递的参数显示在url中,还可以通过发送post请求,在body中传递数据,这样num1和num2就在body行中展示

三、 硬核解析:包装类型 Integer 的"保命"哲学
在代码中,我们使用了 Integer 而非基本类型 int,这是基于企业级开发的避坑经验 。
(一) 规避 500 内部服务器错误
-
int 的局限性 :若前端因网络异常或逻辑错误未传递参数,声明为
int的方法会因无法将null转换给基本类型而直接报错 。 -
Integer 的包容性 :包装类型可以接收
null值 。在实际业务中,这允许我们先接收数据,再通过逻辑判断(如if(num1 == null))给出更友好的提示,而不是让用户直接看到冰冷的 500 错误页面 。
四、 总结与思考
通过这个简单的加法器,我们完成了 Spring MVC "接收请求-处理参数-返回响应"的全流程 。
思考题: 如果前台在 num1 输入框里填了字符串 "abc",我们的程序会发生什么?
-
这种情况下,Spring MVC 会检测到类型不匹配,并向浏览器返回 400 Bad Request 错误状态码 。
2.要想解决这个问题,我们需要在代码中对用户传递的参数进行合法性校验,并且进行非法提示