栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java API接口统一格式返回结果类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java API接口统一格式返回结果类

废话不多说,直接正文。

首先,我们需要定义规则(返回的格式)。如http的返回状态码 404,500,200等。我们都知道404是找不到资源,200是正常的。由此可以知道,每一个状态码都有一个对应的说明。当请求是正常的,我们还需要有存储返回值的地方。

所以返回的格式如下:状态码(code),状态码说明(msg),相应数据(data),这个是比较基础的返回格式。

public class Result implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	//状态码
	private Integer code;
    
	//响应消息
	private String msg;
	
	//响应数据
	private Object data;

	public Integer getCode() {
		return code;
	}

	public void setCode(Integer code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
	
	public Result(ResultCode resultCode,Object data) {
		 this.code=resultCode.getCode();
		 this.msg=resultCode.getMsg();
		 this.data=data;
	}
	public Result(Integer code,String msg,Object data) {
		 this.code=code;
		 this.msg=msg;
		 this.data=data;
	}
	
}

当然也有更复杂的。如下格式:包含分页信息、token身份、模糊查询等。(这个的实现和上面的格式没有什么区别。就是需要建立的实体类要多一些。)

{
    "message": {
        "header": {
            "auth": {
                "callerid": "1552267897663",
                "license": "9425846d54cf4ff0b7d81dd6b922fa75",
                "token": "095A1DA8106527EE81350845611AEEB3",
                "ipaddr": "",
                "macaddr": ""
            },
            "servicecode": {
                "systemcode": "",
                "busscode": "",
                "version": "1",
                "apiurl": ""
            },
            "respon": {
                "code": "1",
                "text": "Token验证正常",
                "detail": null
            }
        },
        "body": {
            "bussresponse": {
                "code": "0",
                "text": "系统异常:系统错误:传入查询编号不适配",
                "detail": "0038e266-5c10-49ef-a614-e4e16257208d"
            },
            "queryresponse": {
                "pageno": 1,
                "pagesize": "",
                "sortfiled": null,
                "sorttype": null,
                "condition": []
            }
            "datacompress": "",
            "dataencrypt": "",
            "dataset": [
                {
                    "name": "",
                    "row": []
                }
            ]
        },
        "extend": {}
    }
}

回归正题,建完实体类后,建枚举定义各个状态码以及说明。

public enum ResultCode {
	
	//成功
	SUCCESS(200,"成功"),
	PARAM_IS_INVALID(1001,"参数无效"),
	PARAM_IS_BLANK(1002,"参数为空"),
	PARAM_IS_ERROR(1004,"参数错误"),
	PARAM_IS_COMPLETE(1003,"参数缺失"),
	USER_LONGIN_ERROR(2001,"账号或密码错误"),
	USER_LONGIN_EXIST(2002,"用户不存在"),
	USER_LONGIN_EXISTD(2003,"用户已存在"),
	KHXX_EXISTD(2010,"客户信息已存在!"),
	USER_LONGIN_EXAMINE(2004,"用户待审核"),
	UPDATE_EXAMINE(2006,"修改申请已提交,等待管理员审核"),
	USER_LONGIN_STOP(2005,"用户已停用"),
	ERROR(500,"系统异常"),
	CUSTOMER_EXISTD(400,"客户信息已存在"),
	PHONE_ERROR(402,"验证码或者手机号错误"),
	PHONE_EXIST(405,"手机号为空"),
	PHONE_RETRY(405,"请2分钟后重试"),
	PHONE_FPRMATEXIST(406,"手机号错误"),
	SINE_ERROR(401,"用户信息已过期,请重新登录"),
	LONG_OVERTIME(406,"登录超时,请重新登录"),
    KHXX_HTJH_EXISTD(1005,"该类型的计划已存在"),
	USER_INSUFFICIENT_AUTHORITY(403,"权限不足"), 
	FILE_NOTBLANK(2007,"上传文件不能为空"),
	FILE_MAXSIZE(2008,"上传文件不能超过2M"),
	FILE_ERRORSUFFIX(2009,"上传文件错误,只能上传文档或表格以及PDF格式");
	
	private Integer code;
	
	private String msg;
   
   public Integer getCode() {
		return code;
	}
	public void setCode(Integer code) {
		this.code = code;
	}
	public String getMsg() {
		return msg;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	ResultCode(Integer code,String msg){
		this.code=code;
		this.msg=msg;
	}

}

这样返回体的格式就定义完了。只需要在代码中使用就行,如下:

public Result queryKhht(JSonObject csjson) {
		if (!csjson.containsKey("khid")) {
			return new Result(ResultCode.PARAM_IS_ERROR,"客户编号不能为空");
		}
		//获取客户合同
		List> khktList = khxxDao.queryKhht(csjson.getInteger("khid"));
        if (khktList.size() >0) {
			for (int i = 0; i < khktList.size(); i++) {
				Map khhtMap=khktList.get(i);
				//获取客户附件
				List> khhtfjList = khxxDao.queryKhhtfj(Integer.valueOf(khhtMap.get("aid").toString()));
				if (khhtfjList.size()>0) {
					khhtMap.put("fjdata", khhtfjList);
				}
						//获取合同回款计划
						List> hkjhList = khxxDao.queryKhhthkjh(Integer.valueOf(khhtMap.get("aid").toString()));
						if (hkjhList.size()>0) {
							khhtMap.put("children", hkjhList);
						}
					}
        }
        return new Result(ResultCode.SUCCESS,khktList);
	}

查询结果展示:

当参数为空时,也可以给到前端明确的提示,如下(ResultCode.PARAM_IS_ERROR对应的枚举是1004,参数错误)

返回结果展示:

可能有的小伙伴也发现了,这样写每一个方法都需要

new Result(枚举,"");看着也不美观。我想只需要return 返回数据体就行 。

下面我们就添加拦截器来实现这个功能。拦截器代码如下。

package com.jmz.ControllerAdvice;

import javax.servlet.http.HttpServletRequest;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.jmz.entity.Result;


@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice {
    
	//标记名称
	private static final String PRESENT_NA_ANN="PRESENT_NA_ANN";
	
	
	public boolean supports(MethodParameter returnType, Class> converterType) {
		Long startTime = System.currentTimeMillis();
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		//根据标记名获取对象   在ResponseResultInterceptor类写入
		ResponseResult rue =(ResponseResult) request.getAttribute(PRESENT_NA_ANN);
		return rue== null ? true : false;
	}

	
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
			Class> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {
		Long startTime = System.currentTimeMillis();
		if (body instanceof Result) {
			return body;
		}
		return new Result(ResultCode.SUCCESS,body);
	}

}
 

测试使用,Controller直接返回list集合

	@RequestMapping("/khxx/getKhdtxx")
	public List> getKhdtxx(@Validated  @RequestBody CrmKhdt khdt) {
		return khxxService.getKhdtxx(khdt);
	}

 postman返回

到此,统一返回体就完成了。但是有一个问题。就是如果我们有部分方法的返回值不需要包装呢?我们现在已经拦截了所有的返回体进行了封装。

所有我这边加了一个自定义注解@ResponseResult来实现这一功能。当我们不需要包装时,只需要在这个方法加上@ResponseResult注解就可以了。

自定义注解@ResponseResult

package com.jmz.ControllerAdvice;

import java.lang.annotation.*;


@Target(ElementType.METHOD)
@documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseResult {

}

验证方法是否包含该注解,如果存在@ResponseResult就不需要封装返回体。

package com.jmz.ControllerAdvice;

import javax.servlet.http.HttpServletRequest;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.jmz.entity.Result;


@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice {
    
	//标记名称
	private static final String PRESENT_NA_ANN="PRESENT_NA_ANN";
	
	
	public boolean supports(MethodParameter returnType, Class> converterType) {
		Long startTime = System.currentTimeMillis();
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		//根据标记名获取对象   在ResponseResultInterceptor类写入
		ResponseResult rue =(ResponseResult) request.getAttribute(PRESENT_NA_ANN);
		return rue== null ? true : false;
	}

	
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
			Class> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {
		Long startTime = System.currentTimeMillis();
		if (body instanceof Result) {
			return body;
		}
		return new Result(ResultCode.SUCCESS,body);
	}

}
 

测试使用

@RequestMapping("/sing/AESDncode")
	@Release
	@ResponseResult
	public String AESDncode(HttpServletRequest request) {
		return AESUtils.AESDncode(request.getParameter("encodeRules"), request.getParameter("content"));
	}
	@RequestMapping("/sing/AESEncode")
	@Release
	@ResponseResult
	public String AESEncode(HttpServletRequest request) {
		return AESUtils.AESEncode(request.getParameter("encodeRules"), request.getParameter("content"));
	}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号