场景

我们团队现在面临着多端数据接口对接的问题,为了解决这个问题我们定义了接口对接的规范,

前端(安卓,Ios,web前端)和后端进行了数据的格式规范的讨论,确定了json的数据格式:

{
"code":"200",
"data":{"":""},
"message":"处理成功"
}
{
"code":"300",
"data":{"":""},
"message":"没有此用户"
}

code代表请求处理状态:200为正常处理,300为业务异常处理,500就系统异常处理。

data代表后台返回的数据。

message后台的提示语,正常或者成功的时候会返回错误原因。

问题来了

让每一个人对每一个json视图的返回值都要进行包装的话,岂不很麻烦,

这个时候AOP就登场了,我们可以利用aop的思想在请求返回json之后还未response到客户端时为其包装上一层。

实现步骤

启用aop

    <!-- base-package 如果多个,用“,”分隔 -->
<context:component-scan base-package="com.we,cn.isuyang">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 打开aop 注解 -->
<aop:aspectj-autoproxy />

创建切面

/**
* json返回切面
* <p>
* 用于处理json返回结果
*
* @author ZhuangJunxiang(529272571@qq.com)
* @Date 2017年4月28日
*/
@Component
@Aspect
@Order(2)
public class JsonReturnAspect { /**
* 设置分页默认值
* <p>
* 如果分页没有设置值,则默认从系统的配置文件里读取
*
* @param pjp 切点
*/
@Around(value = "@annotation(org.springframework.web.bind.annotation.ResponseBody)")
@Order(1)
public Object warp(final ProceedingJoinPoint pjp) throws Throwable {
Object list = pjp.proceed();
if (isReturnVoid(pjp)) {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getResponse();
if (isNeedWrap(pjp)) {
response.getWriter().write(JsonUtil.toJson(success("操作成功")));
}
return list;
}
return data(list);
}
/**
* 是否需要包裹
*
* @param pjp 切点
*
* @return true表示不需要
*/
private boolean isNeedWrap(final ProceedingJoinPoint pjp) {
Method method = AspectUtil.getMethod(pjp);
return !method.isAnnotationPresent(Void.class);
}
/**
* 是否返回空
*
* @param pjp
* @return true:返回类型为void,false:返回类型不是void
*/
private boolean isReturnVoid(ProceedingJoinPoint pjp) {
Method method = AspectUtil.getMethod(pjp);
Class<?> returnType = method.getReturnType();
return "void".equals(returnType.getName());
} /**
* 构建成功后的返回对象
* <p>
* 消息为空时,不提示,不为空则进行提示
*
* @param message 成功消息
* @return json对象
*/
public static Map<String, Object> success(final String message) {
Map<String, Object> map = MapUtil.map();
map.put("code", StatusCode.SUCCESS.key());
map.put("message", message);
map.put("data","");
return map;
}
/**
* 构建成功后的返回对象
* <p>
* 消息为空时,不提示,不为空则进行提示
*
* @param message 成功消息
* @return json对象
*/
public static Map<String, Object> data(final Object data) {
Map<String, Object> map = MapUtil.map();
map.put("code", StatusCode.SUCCESS.key());
map.put("message", message);
map.put("data",data);
return map;
}
}

分析一下

@Component 这个注解表示将这个对象交给spring容器进行实例化

@Aspect 表示这是一个切面类

@Around(value = "@annotation(org.springframework.web.bind.annotation.ResponseBody)")

表示凡是方法上带有@ResponseBody注解的都是这个切面中切点,换句话说都会被拦截。

注意:

warp方法中的ProceedingJoinPoint参数只有环绕通知才可以使用JoinPoint的子类ProceedingJoinPoint,

各连接点类型可以调用代理的方法,并获取、改变返回值。否则就是用JoinPoint。

情况一:假设conroller类中的函数不需要任何返回值

比如:我对一个实体对象进行更新我只需要把更新结果返回去就OK了,不需要填充数据

返回的数据格式:

{

"code":"200",

"data":"",

"message":"处理成功"

}

实现思路:

在切面处理类的处理函数中获取到这个函数的返回值类型如果是void就返回指定格式的数据。

上面的isReturnVoid()就是做这样的一个判断。

你只需要将函数的返回值为void即可:

@RequestMapping
@ResponseBody
public void add(long matchId, Model model) {
slxSignupViewService.setAddInfo(matchId, model);
}

情况二:假设conroller类中的函数的返回值不需要包裹呢

比如:

某些前端插件以及第三方对接(支付)的返回值是规定好的,

以及下载文件,我们这些就是多余了,

实现思路:

自定一个@Void的注解:

/**
* 空注解
* <p>
* 用于标识将controller层中的返回值原模原样的out出去
*
* @author WangSen(wangsenhehe@126.com)
* @Date 2017年8月17日
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Void { }

在controller层的方法上添加这个注解

 /**
* 支付完成
*/
@Void
@ResponseBody
@RequestMapping
public void payFinish() throws IOException {
alipayViewService.payFinish();
}

在这个切面处理类上判断这个函数是否包含这个注解如果包含

就不作处理,原模原样的返回出去。

JsonReturnAspect类中的isNeedWrap()方法就是处理这个需求。

参考资料

http://blog.csdn.net/zx13525079024/article/details/51884234

自定义spring mvc的json视图的更多相关文章

  1. spring mvc返回json字符串的方式

    spring mvc返回json字符串的方式 方案一:使用@ResponseBody 注解返回响应体 直接将返回值序列化json            优点:不需要自己再处理 步骤一:在spring- ...

  2. Spring MVC 数据模型与视图

      从控制器获取数据后,会装载数据到数据模型和视图中,然后将视图名称转发到视图解析器中,通过解析器解析后得到最终视图,最后将数据模型渲染到视图中,展示最终的结果给用户. 用ModelAndView来定 ...

  3. spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable

    1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(val ...

  4. Spring Mvc 输出Json(iwantmoon.com出品)

    原文:http://iwantmoon.com/Post/f94e49caf9b6455db7158474bab4c4dd 因为工作需要,现在要去做开放平台,考虑了多种方案之后,基本确定 下来,Htt ...

  5. Spring MVC 的json问题(406 Not Acceptable)

    原因 : 就是程序转换JSON失败. 在pom.xml 加上 <dependency> <groupId>com.fasterxml.jackson.core</grou ...

  6. spring mvc: 资源绑定视图解析器(不推荐)

    spring mvc: 资源绑定视图解析器(不推荐) 不适合单控制器多方法访问,有知道的兄弟能否告知. 访问地址: http://localhost:8080/guga2/hello/index 项目 ...

  7. spring mvc:内部资源视图解析器2(注解实现)@Controller/@RequestMapping

    spring mvc:内部资源视图解析器2(注解实现)  @Controller/@RequestMapping 访问地址: http://localhost:8080/guga2/hello/goo ...

  8. spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping

    spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping 项目访问地址: http://localhost:8080/guga2/hello/prin ...

  9. ajax使用向Spring MVC发送JSON数据出现 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported错误

    ajax使用向Spring MVC发送JSON数据时,后端Controller在接受JSON数据时报org.springframework.web.HttpMediaTypeNotSupportedE ...

随机推荐

  1. centos 安装giblab

    本文章转载自:http://www.cnblogs.com/fanjingfeng/p/6665597.html 一, 服务器快速搭建gitlab方法 可以参考gitlab中文社区 的教程 cento ...

  2. Phalanx

    Phalanx Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  3. 状压DP小结

    看了一个多星期状压DP,总算有点明白,大概可以分为两种:数据是在矩阵中的,数据是线性的,在矩阵中的一般就是排兵布阵这一种的,还有一种线性结构中给定条件让你求最大权值,比如求最大权值路线,TSP问题等, ...

  4. FPM定制RPM包实践

    1.1 快速部署方案 ✔ 问题:当领导给你 100 台已经安装好系统的服务器,然后让优化,让你提出一个快速部署方案. 解答: 1.tar 打包 先编译安装 打包-->分发-->解包(比如 ...

  5. 【Win 10 应用开发】UI Composition 札记(三):与 XAML 集成

    除了 DirectX 游戏开发,我们一般很少单独使用 UI Composition ,因此,与 XAML 互动并集成是必然结果.这样能够把两者的优势混合使用,让UI布局能够更灵活. 说到与 XAML ...

  6. HTML学习笔记 基础标签及css引用案例 第一节 (原创)参考使用表

    <!DOCTYPE html><!--头文件 不是标签 也没有结束,这是声明该文件为HTML5--><html lang="en"><!- ...

  7. 让盒子两端对齐小技巧 => inline-block

    今天在项目中碰到了设计盒子两端对齐的栗子,咱们用inline-block方法轻松的解决了,下面是我的经验: 原理: 利用文字text-align:justify; 操纵inline-block盒子,能 ...

  8. 如何优雅的设计 React 组件

    作者:晓冬 本文原创,转载请注明作者及出处 如今的 Web 前端已被 React.Vue 和 Angular 三分天下,一统江山十几年的 jQuery 显然已经很难满足现在的开发模式.那么,为什么大家 ...

  9. Flex布局(引用阮一峰大神)

    Flex 布局教程:语法篇 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html Flex 布局教程:实例篇 http://www.ruan ...

  10. MyEclipse和Eclipse非常方便的快捷键

    1. ctrl+shift+r:打开资源这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xml ...