ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

XMall 电商项目 SpringMVC 注解实战全解:从请求映射到全局异常处理的完整技术指南

XMall 电商项目 SpringMVC 注解实战全解:从请求映射到全局异常处理的完整技术指南 电商后端微服务【免费下载链接】xmall基于SOA架构的分布式电商购物商城 前后端分离 前台商城:Vue全家桶 后台管理系统:Dubbo/SSM/Elasticsearch/Redis/MySQL/ActiveMQ/Shiro/Zookeeper等项目地址https://gitcode.com/gh_mirrors/xm/xmall点击查看免费下载本文以 XMall基于 SOA 架构的分布式电商购物商城后台与前台 Web 模块的真实源码为依托系统梳理 SpringMVC 核心注解的用法与底层机制。读者将掌握Controller/RestController的职责分工、RequestMapping各属性value/method/params/headers/produces的匹配规则、参数绑定注解RequestParam/PathVariable/RequestBody/CookieValue的实战姿势以及基于ExceptionHandler构建全局异常处理体系的完整方案。一、写在前面XMall 中 SpringMVC 的位置XMall 是前后端分离的分布式电商项目前台商城使用 Vue 全家桶后台管理系统则基于 Dubbo/SSM/Elasticsearch/Redis/MySQL/ActiveMQ/Shiro/Zookeeper 等技术栈。在后台管理端与前台 Web 端SpringMVC 扮演 Web 层的核心角色前台 Web 端xmall-front-web 暴露/goods/**、/member/**等 REST 接口供 Vue 页面调用后台管理端xmall-manager-web 通过/item/**、/order/**等接口支撑管理后台的 JSP 页面与数据交互。两个工程的请求入口均由 web.xml 中的DispatcherServlet承接配置contextConfigLocation指向 springmvc.xmlurl-pattern设为/拦截所有请求load-on-startup设为 1 保证容器启动即加载。SpringMVC 的“注解驱动”开发模式正是从这一入口开始贯穿整个 Web 层。下面以注解为主线展开。二、控制器定义注解Controller 与 RestControllerController通过Controller标注即可将 class 定义为一个 controller 类交由 Spring 容器管理并参与 SpringMVC 的请求分发。通常配合视图解析器返回 JSP 页面名由InternalResourceViewResolver完成视图渲染。RestControllerRestController是Controller与ResponseBody的组合注解类上标注后该类所有方法的返回值都会直接写入 HTTP Response Body而不是走视图解析。在 XMall 前后端分离架构中前台与后台的控制器几乎全部采用RestController// xmall-front-web/src/main/java/cn/exrick/front/controller/GoodsController.java RestController Api(description 商品页面展示) public class GoodsController { ... }// xmall-front-web/src/main/java/cn/exrick/front/controller/MemberController.java RestController Api(description 会员注册登录) public class MemberController { ... }商品管理端同样如此ItemController.java 以RestController标注并配合ApiSwagger注解生成接口文档。从源码结构看XMall 中的RestController返回值统一封装为Result/DataTablesResult等 JSON 结构如 ResultUtil由 Jackson 等 JSON 转换器序列化后返回前端这正体现了RestController在前后端分离项目中的典型用法——控制器只负责数据契约视图层完全交给前端框架。三、请求映射注解RequestMapping 的五大属性RequestMapping用于将 URL 映射到处理方法其核心属性如下。value —— 需要匹配的 URL 格式RequestMapping(value /member/add, method RequestMethod.POST)method —— 所需处理请求的 HTTP 协议get、post、put、delete 等method用于限定请求方法不匹配时 SpringMVC 返回 405。上面示例即表示只有 POST 请求/member/add才会进入该方法。params —— 请求参数约束格式为paramnameparamvalue或paramname!paramvalue表示参数必须等于某值、不等于某值或必须存在时才进入此映射方法不填写时表明不限制。示例当请求/testParams.do?param1value1param2value2时能正确访问到testParams方法RequestMapping(value testParams, params { param1value1, param2, !param3 }) public String testParams() { System.out.println(test Params...........); return testParams; }headers —— 请求头约束用来限定对应 request 请求的 headers 中必须包括的内容。例如headers{Connectionkeep-alive}表示请求头中 connection 的值必须为 keep-alive。当请求/testHeaders.do时只有当请求头包含Accept信息且请求的 host 为localhost时才能正确访问到testHeaders方法RequestMapping(value testHeaders, headers { hostlocalhost, Accept }) public String testHeaders() { return headers; }produces —— 指定返回的内容类型指定返回的内容类型仅当 request 请求头中的 Accept 类型中包含该指定类型才返回同时该值也会写入响应的Content-Type头控制返回内容的媒体类型与字符集RequestMapping(value testProduces, produces text/plain;charsetutf-8) RequestMapping(value testProduces, produces application/json;charsetutf-8) RequestMapping(value testProduces, produces application/xml;charsetutf-8)XMall 实战印证produces在前台商品快速搜索接口中得到直接应用——GoodsController.java 中RequestMapping(value /goods/quickSearch, produces text/plain;charsetUTF-8, method RequestMethod.GET) ApiOperation(value 快速搜索) public String getQuickSearch(RequestParam(defaultValue ) String key){ return searchService.quickSearch(key); }这里显式声明以text/plain;charsetUTF-8返回纯文本同时解决了中文乱码问题是produces在真实项目中的典型用法。四、组合映射注解GetMapping / PostMapping / PutMapping / DeleteMapping四个组合注解分别映射 HTTP 的 get、post、put、delete 请求。DeleteMapping等同于RequestMapping(value /member/add, method RequestMethod.DELETE)其余同理是RequestMapping(method...)的语义化简写。虽然 XMall 的前台控制器主要使用完整的RequestMapping(value ..., method RequestMethod.X)写法这是 SSM 项目中较常见的风格但从 Spring 4.3 开始官方推荐使用组合注解二者的等价关系如下组合注解等价写法GetMapping(/url)RequestMapping(value /url, method RequestMethod.GET)PostMapping(/url)RequestMapping(value /url, method RequestMethod.POST)PutMapping(/url)RequestMapping(value /url, method RequestMethod.PUT)DeleteMapping(/url)RequestMapping(value /url, method RequestMethod.DELETE)XMall 实战印证商品管理端 ItemController.java 完整演示了 PUT 与 DELETE 的语义化用法// 下架商品PUT 语义更新状态 RequestMapping(value /item/stop/{id}, method RequestMethod.PUT) public ResultTbItem stopItem(PathVariable Long id){ TbItem tbItem itemService.alertItemState(id, 0); return new ResultUtilTbItem().setData(tbItem); } // 删除商品DELETE 语义支持批量删除路径参数为数组 RequestMapping(value /item/del/{ids}, method RequestMethod.DELETE) public ResultTbItem deleteItem(PathVariable Long[] ids){ for(Long id : ids){ itemService.deleteItem(id); } return new ResultUtilTbItem().setData(null); }可以看到 REST 语义被贯彻到了 URL 设计与方法选择中查询用 GET、新增用 POST、状态变更用 PUT、删除用 DELETE这正是RequestMapping(method...)在实际架构中的价值。五、参数绑定注解RequestParam、PathVariable、RequestBody、CookieValue5.1 RequestParam —— 绑定请求参数属性说明value对应表单 name 空间的值即请求参数名required是否允许为空默认为 true缺省时参数缺失会报 400 错误defaultValue默认值设置后 required 自动失效参数缺失时使用默认值。RequestMapping(requestParam) public String testRequestParam(RequestParam(required false) String name, RequestParam(age) int age) { return requestParam; }XMall 实战印证分页、排序、筛选等列表查询参数最适合用RequestParam配合默认值见 GoodsController.javaRequestMapping(value /goods/allGoods, method RequestMethod.GET) public ResultAllGoodsResult getAllProduct(RequestParam(defaultValue 1) int page, RequestParam(defaultValue 20) int size, RequestParam(defaultValue ) String sort, RequestParam(defaultValue ) Long cid, RequestParam(defaultValue -1) int priceGt, RequestParam(defaultValue -1) int priceLte){ AllGoodsResult allGoodsResult contentService.getAllProduct(page, size, sort, cid, priceGt, priceLte); return new ResultUtilAllGoodsResult().setData(allGoodsResult); }管理端 ItemController.java 甚至直接绑定 DataTables 表格的搜索框与排序列名search[value]、order[0][column]、order[0][dir]让前端表格组件与后端参数无缝对接。5.2 PathVariable —— 绑定 URL 路径模板变量PathVariable获得地址栏中传的参数REST 风格的 URL 路径参数RequestMapping(value /{groupId}.do) public void detail(PathVariable long groupId){ groupRepository.selectOne(groupId); }XMall 实战印证商品详情与状态操作大量使用路径变量见 ItemController.javaRequestMapping(value /item/{itemId}, method RequestMethod.GET) ApiOperation(value 通过ID获取商品) public ResultItemDto getItemById(PathVariable Long itemId){ ItemDto itemDto itemService.getItemById(itemId); return new ResultUtilItemDto().setData(itemDto); }注意PathVariable默认为必填若 URL 模板中没有对应占位符会抛出MissingPathVariableException。批量删除接口PathVariable Long[] ids则展示了路径变量支持数组绑定/item/del/1,2,3的扩展用法。5.3 RequestBody —— 将请求体转换为 Java 实体RequestBody用来将客户端发送过来的请求参数数据格式JSON/XML 等转换成 Java 实体RequestMapping(value /xxxxx.do) public void create(RequestBody() String host){ System.out.println(----------- host); }在前后端分离架构中前端提交的 JSON 对象通常通过RequestBody直接反序列化为 DTO 实体。XMall 实战印证会员登录接口将极验验证参数与账号密码整体封装进MemberLoginRegist对象见 MemberController.javaRequestMapping(value /member/login, method RequestMethod.POST) ApiOperation(value 用户登录) public ResultMember login(RequestBody MemberLoginRegist memberLoginRegist, HttpServletRequest request){ ... }头像上传接口同样用RequestBody CommonDto接收 base64 图片数据MemberController.java体现了RequestBody对复杂嵌套 JSON 的承载能力。需要留意的是RequestBody与RequestParam职责不同——前者读取整个消息体后者读取 URL 或表单字段二者可以并存于同一方法签名中。5.4 CookieValue —— 绑定请求头中的 Cookie 值CookieValue可以把 Request header 中关于 cookie 的值绑定到方法的参数上。例如有如下 Cookie 值JSESSIONID415A4AC178C59DACE0B2C9CA727CDD84即可把JSESSIONID的值绑定到参数cookie上RequestMapping(/displayHeaderInfo.do) public void displayHeaderInfo(CookieValue(JSESSIONID) String cookie) { }这在需要读取会话标识、自动登录票据或埋点追踪 ID 的场景中非常实用。与RequestParam类似它同样支持required与defaultValue属性。六、响应状态注解ResponseStatusResponseStatus返回一个指定的 HTTP response 状态码可直接标注在方法上或异常类上配合value与reason两个属性使用ResponseStatus(reason no reason, value HttpStatus.BAD_REQUEST) RequestMapping(/responsestatus) public void responseStatusTest(){ }标注后SpringMVC 会将该方法映射的响应状态码设置为HttpStatus.BAD_REQUEST400reason则作为响应体中的错误原因返回。XMall 实战印证全局异常处理器 RestCtrlExceptionHandler.java 中对参数绑定异常BindException显式声明ResponseStatus(value HttpStatus.OK)ExceptionHandler(BindException.class) ResponseStatus(value HttpStatus.OK) ResponseBody public ResultObject bindExceptionHandler(BindException e){ String errorMsg 请求数据校验不合法: ; if(e ! null){ errorMsg e.getMessage(); log.warn(errorMsg); } return new ResultUtil().setErrorMsg(errorMsg); }这里刻意将业务异常统一回 200 并在 JSON 体中携带错误信息是前端友好型接口设计的常见取舍——HTTP 层不报错业务层通过Result的state/message字段表达成败避免前端因跨域或代理配置丢失非 2xx 状态码。七、异常处理注解ExceptionHandler 与全局异常体系ExceptionHandler用于处理控制器方法抛出的异常可声明在单个控制器内也可通过ControllerAdvice提升为全局处理RequestMapping(/exception) public void ExceptionTest() throws Exception{ throw new Exception(i dont know); } ExceptionHandler public String handleException(Exception e, HttpServletRequest request){ System.out.println(e.getMessage()); return helloworld; }当/exception抛出异常时SpringMVC 会查找可处理该异常类型的方法handleException并执行方法可声明Exception e与HttpServletRequest request等参数。XMall 实战印证XMall 将异常处理升级为全局统一体系前台 RestCtrlExceptionHandler.java 通过ControllerAdvice覆盖所有控制器按异常类型分级处理ControllerAdvice public class RestCtrlExceptionHandler { // 参数绑定异常 ExceptionHandler(BindException.class) ResponseStatus(value HttpStatus.OK) ResponseBody public ResultObject bindExceptionHandler(BindException e){ ... } // 业务自定义异常xmall-common 中的 XmallException ResponseStatus(value HttpStatus.OK) ExceptionHandler(XmallException.class) ResponseBody public ResultObject handleXmallException(XmallException e) { String errorMsg Xmall exception: ; if (e ! null){ errorMsg e.getMsg(); log.warn(e.getMessage()); } return new ResultUtil().setErrorMsg(errorMsg); } // 兜底异常识别文件上传超限、XmallException 等常见错误 ExceptionHandler(Exception.class) ResponseStatus(value HttpStatus.OK) ResponseBody public ResultObject handleException(Exception e) { ... } }该设计有几点值得学习自定义业务异常基于 XmallException 承载业务错误语义与ExceptionHandler(XmallException.class)形成一一对应的处理分支兜底策略handleException对Maximum upload size、XmallException:等消息做二次解析将底层异常转换为用户可读的中文提示如“上传文件大小超过5MB限制”与 springmvc.xml 中multipartResolver的maxUploadSize52428805MB限制相互印证统一返回结构所有异常均包装为Result对象输出保证前端异常处理逻辑的一致性。八、综合实战从注解到完整 REST 控制器结合 XMall 前台 GoodsController.java可以看到一篇真实控制器如何将这些注解组合成一个完整的商品查询 APIRestController Api(description 商品页面展示) public class GoodsController { Autowired private ContentService contentService; Autowired private SearchService searchService; // 获取导航栏GET 请求无参数 RequestMapping(value /goods/navList, method RequestMethod.GET) public ResultListTbPanelContent getNavList(){ ListTbPanelContent list contentService.getNavList(); return new ResultUtilListTbPanelContent().setData(list); } // 商品搜索RequestParam 默认值 produces 限定返回类型 注入 ES 搜索服务 RequestMapping(value /goods/search, method RequestMethod.GET) public ResultSearchResult searchProduct(RequestParam(defaultValue ) String key, RequestParam(defaultValue 1) int page, RequestParam(defaultValue 20) int size, RequestParam(defaultValue ) String sort, RequestParam(defaultValue -1) int priceGt, RequestParam(defaultValue -1) int priceLte){ SearchResult searchResult searchService.search(key, page, size, sort, priceGt, priceLte); return new ResultUtilSearchResult().setData(searchResult); } }一个标准的 XMall REST 控制器通常遵循如下模式类级RestController声明 JSON 输出 Api接入 Swagger 文档Swagger2Config.java 通过RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)扫描带ApiOperation的方法生成接口文档方法级RequestMapping或组合注解声明 URL 与 HTTP 方法ApiOperation描述接口语义参数级查询参数用RequestParam配合默认值兜底、路径参数用PathVariable、JSON 体用RequestBody返回值统一封装ResultT由ResultUtil构建异常由ControllerAdviceExceptionHandler全局兜底。九、扩展观察注解之外的处理链SpringMVC 的价值不仅在于注解本身。从 XMall 源码可以看到注解与周边组件的协作关系拦截器前台 LimitRaterInterceptor.java 基于HandlerInterceptorAdapter实现 IP 限流与全局限流结合 RedisRaterLimiter.java并在preHandle中通过HandlerMethod.getMethod()读取方法上的RateLimiter注解RateLimiter.java实现方法级限流——这是“注解 拦截器”协同的经典范式前端控制器DispatcherServlet负责把请求分发到上述注解标注的方法其装配在 springmvc.xml 中完成context:component-scan base-packagecn.exrick.front/扫描控制器与拦截器 Beanmvc:resources映射 Swagger 静态资源Dubbo 服务引用控制器通过Autowired注入的 Service 实际是 Dubbo 远程引用见 springmvc.xml 中的dubbo:reference注解驱动让远程服务调用对控制器透明这是 SOA 架构与 SpringMVC 无缝结合的关键。十、小结SpringMVC 的注解体系是 Web 层开发的基石。通过 XMall 源码可以看到RestController支撑前后端分离的 JSON 契约RequestMapping及其组合注解构建清晰的 REST 路由RequestParam/PathVariable/RequestBody覆盖查询、路径、消息体三种参数来源CookieValue读取会话凭证ResponseStatus控制响应语义而ControllerAdviceExceptionHandler则把散落的异常处理收敛为统一防线。读者在阅读 SpringMVC.md 笔记之余可对照 XMall 的 front 控制器目录、manager 控制器目录 与全局异常处理器逐注解验证其在真实分布式电商场景中的落地方式。赞分享电商后端微服务【免费下载链接】xmall基于SOA架构的分布式电商购物商城 前后端分离 前台商城:Vue全家桶 后台管理系统:Dubbo/SSM/Elasticsearch/Redis/MySQL/ActiveMQ/Shiro/Zookeeper等项目地址https://gitcode.com/gh_mirrors/xm/xmall点击查看免费下载相关推荐LKY_OfficeTools一键自动化Office部署的终极解决方案 LKY_OfficeTools一键自动化Office部署的终极解决方案 在当今数字化办公环境中Microsoft Office已成为企业日常运营和个人桌面应用CLIArcKit Claude Code插件完全指南17插件市场、依赖安装与自动更新ArcKit Claude Code插件完全指南17插件市场、依赖安装与自动更新 ArcKit 是一款面向企业架构治理的 AI 工具箱EnterpriseCLI开发工具企业应用AI 技能MCP ClientsPyAnnote Audio实战指南构建高效说话人识别系统的完整方案PyAnnote Audio实战指南构建高效说话人识别系统的完整方案 PyAnnote Audio是一个基于PyTorch的深度学习音频处理框架专注于说话人人工智能语音音频深度学习预训练微调上一篇Test Infrastructure下一篇angular/google-maps MapPolyline 完全指南在 Angular 中绘制与管理 Google 地图折线创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表