SpringMVC利用注解 规范http接口返回值
SpringMVC利用注解 规范http接口返回值
一般在项目构建时,会选择定义基础接口返回值规范实体,并直接规定返回实体,但在控制器上对实体的进行的实例化会产生多余代码,为了减少这一部门的冗余代码,部分项目会采用注解的方式或者直接全局使用切面来处理返回值。以下我将介绍一下我的处理方案。
实现代码:
注解代码:
import java.lang.annotation.*; /** * 如果该注解的方法出现异常,则会反馈标准的异常结果【ResponseMsg.java】给前端或者服务调用方 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyResponse { }
返回值实体用于测试,具体的web应用,可以具体使用项目的规范,以下只是测试时使用的实体规范,具体应用时可以根据具体需要来拼装数据
import lombok.Data; /** * 接口默认返回参数 * lombok.Data 可以改成直接写入封装方法 */ @Data public class ResponseMsg { /** * 代码 */ private int code; /** * 消息 */ private String msg; /** * 是否成功 */ private boolean success; /** * 数据 */ private Object data; }
自定义异常,用于测试,同理可根据具体项目需求改变
import lombok.Data; @Data public class MyException extends RuntimeException{ private int code; /** * 构造 */ public MyException(int code, String msg) { super(msg); this.code = code; } }
关键代码,返回值切面,JSON,Slf4j类根据具体项目依赖处理,此处为了减少代码增加了这个类。
实际就是利用切面获取返回值并拼装,处理Object及void类型,并通过捕捉切点的异常封装返回值。
建议将切面位置提前,保证其他切面的异常不影响返回值的规范。
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import self.aop.anno.MyResponse; import self.aop.model.ResponseMsg; import self.exception.MyException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 使用AOP拦截出现异常的Controller的方法,并反馈标准的异常描述 * * @Slf4j可以去掉,换成手动的log */ @Order(1) @Aspect @Component @Slf4j public class ResponseAspect { private static final String VOID = "void"; private static final int ERR_CODE = 500; @Around(value = "@annotation(catchErr)") public Object doAudit(ProceedingJoinPoint point, MyResponse catchErr) throws Throwable { Object returnVal; ResponseMsg resultMsg; try { returnVal = point.proceed(); } catch (MyException ex) { resultMsg = new ResponseMsg(); resultMsg.setCode(ex.getCode()); resultMsg.setMsg(ex.getMessage()); resultMsg.setSuccess(false); writeResultMessage2Writer(point, resultMsg); log.info("{}", ex); return resultMsg; } catch (Exception ex) { resultMsg = new ResponseMsg(); resultMsg.setCode(ERR_CODE); resultMsg.setMsg(ex.getMessage()); resultMsg.setSuccess(false); writeResultMessage2Writer(point, resultMsg); log.error("{}", ex); return resultMsg; } resultMsg = new ResponseMsg(); resultMsg.setCode(200); resultMsg.setMsg("成功"); resultMsg.setSuccess(true); Class returnType = ((MethodSignature) point.getSignature()).getReturnType(); if (StringUtils.equals(returnType.getName(), VOID)) { writeResultMessage2Writer(point, resultMsg); } resultMsg.setData(returnVal); return resultMsg; } /** * 返回void情况下单独做response处理防止无法输出 * @param point 切点 * @param resultMsg 消息实体 * @throws IOException io异常 */ private void writeResultMessage2Writer(ProceedingJoinPoint point, ResponseMsg resultMsg) throws IOException { Class returnType = ((MethodSignature) point.getSignature()).getReturnType(); if (!StringUtils.equals(returnType.getName(), VOID)) { return; } HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); response.setCharacterEncoding("UTF-8"); response.setHeader("content-type", "application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(resultMsg, SerializerFeature.PrettyFormat)); } }
以下是测试使用的web控制器
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import self.aop.anno.MyResponse; import self.exception.MyException; /** * 返回值规范测试控制器 */ @Controller @RequestMapping("response/msg") public class ResponseMsgController { @PostMapping("/object") @MyResponse @ResponseBody public Object objectFunction(){ return "data"; } @PostMapping("/void") @MyResponse @ResponseBody public void voidFunction(){} @PostMapping("/my/exception") @MyResponse @ResponseBody public void myExceptionFunction(){ throw new MyException(501,"手动抛自定义异常"); } @PostMapping("/exception") @MyResponse @ResponseBody public void exceptionFunction(){ throw new RuntimeException("手动抛其他异常"); } }
Object类型返回值
void类型返回值
自定义异常返回值
其他异常返回值
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
生成多个ssh key添加到ssh-agent测试连接报错
ssh key添加到ssh-agent测试连接报错 ssh -T git@github.com 如下报错,说明是~/.ssh/config文件问题.ssh/config: line 5: Bad configuration option: usekeychain修改配置文件解决问题,完整流程看这里Mac系统如下 Host new HostName github.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_rsa_new User test Host old HostName github.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_rsa User test Win系统如下 Host new HostName github.com IdentityFile C:\\Users\Eric\.ssh\id_rsa_new PreferredAuthentications publickey User Eric Host old Ho...
- 下一篇
Async/Await替代Promise的6个理由
译者按: Node.js的异步编程方式有效提高了应用性能;然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码;在实践过程中,却发现Promise并不完美;技术进步是无止境的,这时,我们有了Async/Await。 原文: 6 Reasons Why JavaScript’s Async/Await Blows Promises Away 译者: Fundebug 为了保证可读性,本文采用意译而非直译。 Node.js 7.6已经支持async/await了,如果你还没有试过,这篇博客将告诉你为什么要用它。 Async/Await简介 对于从未听说过async/await的朋友,下面是简介: async/await是写异步代码的新方式,以前的方法有回调函数和Promise。 async/await是基于Promise实现的,它不能用于普通的回调函数。 async/await与Promise一样,是非阻塞的。 async/await使得异步代码看起来像同步代码,这正是它的魔力所在。 Async/Await语法 示例中,getJSON函数返回一个promise...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度