您现在的位置是:首页 > 文章详情

SpringMVC利用注解 规范http接口返回值

日期:2019-04-24点击:521

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类型返回值

image

void类型返回值

image

自定义异常返回值

image

其他异常返回值

image

原文链接:https://yq.aliyun.com/articles/699836
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章