您的位置 首页 java

Restful服务如何优雅地统一返回数据的格式(附源码)

我们在做Restful服务接口规范时,通常都希望返回的结果有一个统一的格式,譬如在返回结果中定义固定的三个属性,比如下面的结构:

 @ApiModelProperty(value = "结果编码,0:成功,其他:错误编码。")
int getCode();

@ApiModelProperty(value = "code=0:消息:code!=0:错误信息。")
 String  getMessage();

@ApiModelProperty(value = " Json 格式的数据内容,根据业务的需要定义;前端可以通过在线调试查看详细信息。")
Object getData();  

但是这样做每个接口的返回结果都变成这个结构,就无法知道接口实际返回结果的内容了(就是data的结构),这里分享一个优雅的解决方案。

定义注解

声明一个自定义注解WrapUpResponseBody用来替代ResponseBody注解。

 @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WrapUpResponseBody  {
    /**
     * 用来指定 封装类别
     * @return String  contentType
     */
    WrapUpContentType  contentType () default WrapUpContentType.DATA;
}  

定义一个 Handler MethodReturnValueHandler类用来统一结果的格式,自动添加上code和message。

 public class WrapUpResponseBodyReturnValueHandler implements HandlerMethodReturnValueHandler {
 		@Override
    public  void  handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWeb request  webRequest)
        throws IO Exception , HttpMessageNotWritableException {

        mavContainer.setRequestHandled(true);
        ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);

        // Try even with null return value. WrapUpResponseBodyAdvice could get involved.
        writeWithMessageConverters(returnValue, returnType, outputMessage);
    }
}  

异常结果处理

上面的方式只能统一处理正确返回结果的情况,如果想返回错误信息如何处理呢;可以通过统一的异常处理来解决。

定义一个统一的异常数据结构,包括错误代码和信息。

 public class ObjectException  extends  RuntimeException {
    //错误号  
    protected int exceptionCode;
    //用于跟踪的数据,可以放到返回结果的data中
     private  Object objectData;
}  
 @ExceptionHandler
public void exceptionHandler(Exception ex, HttpServletRequest request, HttpServletResponse response)
throws IOException {
  ........
  //responseData 含有code、message、data属性
  //在同一个异常处理中返回符合标准的数据格式
  ResponseMapData responseData =
    new ResponseMapData(objex.getExceptionCode(),
                        ObjectException.extortExceptionOriginMessage(objex));
  responseData.addResponseData("trace",ObjectException.extortExceptionTraceMessage(objex));
  responseData.addResponseData("object",objex.getObjectData());
  JsonResultUtils.writeResponseDataAsJson(responseData, response);
  .......
}  

如何返回其他格式的结果

但有时需要返回数据流比如文件,或者和和第三方约定的接口格式和这个标准格式不一致怎么办,这是可以利用注解的contentType内容类别属性:

 /**
 * 包装器内容类别
 */
public enum WrapUpContentType {
    DATA, // json data,默认属性,返回json格式的数据
    RAW,  // 返回函数返回值的元素数据,如果不是String类型,转换为String类型,非标量类型转换为json, 等价于 @RespondBody
    JAVASCRIPT, // 返回脚本
    IMAGE, // 返回图片流
    XML,  //将对象转换为xml返回
     HTML , // 返回html文本
    FILE, // 返回文件流
    MAP_DICT // 将对象中的 DictionaryMap 注解 映射为 对应的字段添加到json
}
  

总结

通过注解和异常来统一处理返回结果的格式,这样接口方法就可以根据实际情况返回结果数据,不会影响单元测试,并且开发人员不需要知道接口的数据包装形式。

南大先腾开源框架:

文章来源:智云一二三科技

文章标题:Restful服务如何优雅地统一返回数据的格式(附源码)

文章地址:https://www.zhihuclub.com/185181.shtml

关于作者: 智云科技

热门文章

评论已关闭

2条评论

网站地图