场景

笔者们公司未来面临着多端数据接口对接的题材,为了化解那几个标题我们定义了接口对接的标准,
前端(安卓,Ios,web前端)和后端举行了数据的格式规范的议论,确定了json的数量格式:

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

code代表呼吁处理状态:200为健康处理,300为业务分外处理,500就系统丰裕处理。
data代表后台重返的数量。
message后台的提醒语,不荒谬大概成功的时候会再次回到错误原因。

题材来了

让每一位对每3个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 =
%22@annotation(org.springframework.web.bind.annotation.ResponseBody)”)

意味着凡是方法上带有@ResponseBody申明的都以那些切面中切点,换句话说都会被截留。

注意:
warp方法中的ProceedingJoinPoint参数唯有环绕通告才方可采取JoinPoint的子类ProceedingJoinPoint,
各连接点类型可以调用代理的方法,并赢得、改变重回值。否则就算用JoinPoint。

动静一:若是conroller类中的函数不要求任何再次来到值

比如:作者对1个实体对象举办立异自身只要求把创新结果再次来到去就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

相关文章

网站地图xml地图