用一个切面来统一返回前端的JSON格式

新项目使用Spring MVC + MyBatis架构来做,这套框架自己应该比较得心应手,这里来写一下这两天做的一些设计。

首先是静态资源的处理,关于这个之前有写文章单独讲过,这里不再重复写,不太清楚的童鞋可以移步查看

接着需要统一JSON的返回格式,和前端工程师约定,对于字符串类型和日期类型都返回字符串,而对于普通数字类型的话都返回数字,金额类数字都返回格式化好的保留一位小数的字符串(比如”10.0”),另外数字和金额的默认值为0,而字符串的默认值为字符串空(“”),并且对于返回的格式也有规范,所有的JSON返回必须形如:

{“status”: 1,”data”: data,”msg”: “”}

其中:

下面,我们首先需要对默认的Jackson的序列化规则做出修改,这里自定义一个ObjectMapper:

/** * 自定义jackson解析器 * @author Zhu * @date 2015-5-14 * @version 0.0.1 * @description */{/****/serialVersionUID = 1L;/****/public CustomerObjectMapper() {super();.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){(Object value, JsonGenerator generator,SerializerProvider provider) throws IOException,JsonProcessingException {generator.writeString(“”);}});}}

然后将我们自定义的ObjectMapper注入到MappingJackson2HttpMessageConverter中去并重新配置Spring MVC中的message converter

==>>></mvc:annotation-driven>

接下来,我们可以在Controller方法上添加@ResponseBody注解来返回JSON(这里需要说一句,classpath下需要有jackson的jar包,这是前提),,但是这就要求我们在每个Controller方法中都进行一些重复的工作,比如:

public ModelMap getUserList(){ModelMap modelMap = new ModelMap();try {modelMap.put(“status”, 1);modelMap.put(“data”, userSerivce.getUserList());modelMap.put(“”, “”);} catch (Exception e) {modelMap.put(“status”, 0);modelMap.put(“data”, “”);modelMap.put(“msg”, e.getMessage());logger.error(“getUserList occurs error:”, e);}}

这样的重复代码在项目中不建议出现,我们其实只需要关心其中的data就可以了,所以我打算将其统一写到一个方法中,并且这也有利于以后对于公共结构的更改。下面就是一个切面来统一处理所有的接口:

/** * 其中ResponseBase类和注解类CustomResponseBody都是自己写的 *//** * @author Zhu * @date 2015-5-18 * @version 0.0.1 * @description 负责将返回转换成统一消息格式 * 序列化为的格式如下: * {“status”: 1,”data”: data,”msg”: “”}其中被注解的方法只需要关心data的内容即可 */{@Resourceprivate MappingJackson2HttpMessageConverter converter;private final Logger logger = LoggerFactory.getLogger(getClass());/*** 拦截所有@ResponseBody* @author Zhu* @date 2015-5-18上午11:32:26* @description*/@Pointcut(“execution(* com.xxx.*.web.controller.*.*(..)) && @annotation(com.xxx.common.annotation.CustomResponseBody)”)() {}/*** @author Zhu* @date 2015-5-18上午11:35:42* @description* @param pjp* @throws Throwable*/@Around(value = “responseBodyPointCut()”)(ProceedingJoinPoint pjp) throws Throwable {Object ret = pjp.proceed();ResponseBase responseBase = new ResponseBase();responseBase.setData(ret);HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);converter.write(responseBase, MediaType.APPLICATION_JSON, outputMessage);shutdownResponse(response);}/**** @author Zhu* @date 2015-5-18下午6:01:46* @description* @param jp* @param error* @throws Throwable*/@AfterThrowing(pointcut = “responseBodyPointCut()”, throwing = “error”)(JoinPoint jp, Throwable error) throws Throwable{ResponseBase responseBase = new ResponseBase();responseBase.setStatus(0);responseBase.setMsg(error.getMessage());HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();logger.error(jp.getSignature().getName() + “-error!”, error);HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);converter.write(responseBase, MediaType.APPLICATION_JSON, outputMessage);shutdownResponse(response);}(HttpServletResponse response) throws IOException{response.getOutputStream().close();}}

当然这里有几个关键点,需要提一下:

其余的内容后续再写吧,现在手头上项目太多,需要整理的东西也太多了~

生活不要太劳累,弄得自己很疲惫,快乐幸福多体会,

用一个切面来统一返回前端的JSON格式

相关文章:

你感兴趣的文章:

标签云: