自定义spring mvc的json视图

场景

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

前端(安卓,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([email protected])
 * @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([email protected])
 * @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

时间: 2024-10-28 08:21:30

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

Spring MVC返回json视图时,如何将对象直接序列化成不带变量名做为根节点

Spring MVC返回json视图时,如何将对象直接序列化成不带变量名做为根节点的 json 报文 问题 问题描述起来比较拗口,其实就是用Spring MVC时,如何将对象映射成 json 报文时不把对象作为json的根节点.即使用@ResponseBody的效果. 比如,默认情况下,使用ModelAndView的addObject(key,object)或者ModelMap的addAttribute(key,object)保存完Java对象,然后交给Srping的视图解析器解析成json时,

spring mvc velocity多视图

1.ViewResolverUrlBasedViewResolver 这个东西是根据url 进行路由的.网上搜了 1.order 排序,同名出现各种问题 2.XmlViewResolver,BeanNameViewResolver,ResourceBundleViewResolver 这个 根据配置文件去找不同的view 乱码...莫名,而且配置的起来比较麻烦,好处么,就是一个配置文件基本搞定所有页面位置 乱码据说WebApplicationContext 中可以设置某弄过 3.自己写个View

spring mvc返回json字符串的方式

spring mvc返回json字符串的方式 方案一:使用@ResponseBody 注解返回响应体 直接将返回值序列化json            优点:不需要自己再处理 步骤一:在spring-servlet.xml文件中配置如下代码 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans&quo

关于 Spring MVC 返回 json 字符串

Spring MVC 返回 json 字符串的几种方式: 1.通过 @ResponseBody 注解自动将返回对象转为 json,这种方法需要 jackson-core.jar 等相关 jar 包支持,项目如果通过 maven 管理,直接在 maven 中加入依赖: ,这样在 maven 依赖中会新增完整的三个 jar 包: 2.在 spring-MVC 配置文件中进行默认视图配置: 3.借助其他 json 工具进行转换:比如可以使用 gson 来完成转换,当然这种方式也得需要 gson 的相关

Spring MVC 的json问题(406 Not Acceptable)

原因 : 就是程序转换JSON失败. 在pom.xml 加上 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.2</version> </dependency> spring mvc 转化JSON 它所使用的json转换器是http:

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

1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(value = { "/actor_details" }, method = { RequestMethod.POST }) @ResponseBody public ResultObject actorDetails(@RequestBody ActorDetailsRequest req)

Spring MVC 结合Velocity视图出现中文乱码的解决方案

编码问题一直是个很令人头疼的事,这几天搭了一个Spring MVC+VTL的web框架,发现中文乱码了,这里记录一种解决乱码的方案. 开发环境为eclipse,首先,检查Window->preferences->workplace->Text File Encoding,设置为GBK .vm文件中加入编码约束,举例如下 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Typ

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

原文:http://iwantmoon.com/Post/f94e49caf9b6455db7158474bab4c4dd 因为工作需要,现在要去做开放平台,考虑了多种方案之后,基本确定 下来,Http Api and Web Serivce两种,REST API 就需要通过Spring Mvc输出Json,这里面其实还是有一些工作可以做的,比如大量用户访问的情况下,怎保证性能.保证流量和稳定性.当然本篇我们还是主要讨论如何去实现它. 接下来,大家跟着我做吧. 首先,我们要了解Spring Mv

Spring MVC资源绑定视图解析器

ResourceBundleViewResolver使用属性文件中定义的视图bean来解析视图名称. 以下示例显示如何使用Spring Web MVC框架中的ResourceBundleViewResolver. ResourceBundleViewResolver-servlet.xml 配置如下所示 - <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"> <p