一,统一返回数据结构
定义返回的数据结构
package com.futao.springmvcdemo.model.system;import org.joda.time.DateTime;import java.sql.Timestamp;/** * @author futao * Created on 2018/9/22-21:47. * 统一返回Rest风格的数据结构 */public class RestResult { /** * 请求是否成功 */ private boolean success; /** * 成功或者失败的code错误码 */ private String code; /** * 成功时返回的数据,失败时返回具体的异常信息 */ private Object data; /** * 请求失败返回的提示信息,给前端进行页面展示的信息 */ private Object errorMessage; /** * 服务器当前时间(添加该字段的原因是便于查找定位请求时间,因为实际开发过程中服务器时间可能跟本地时间不一致,加上这个时间戳便于日后定位) */ private Timestamp currentTime; public RestResult() { } @Override public String toString() { return "RestResult{" + "success=" + success + ", code='" + code + '\'' + ", data=" + data + ", errorMessage=" + errorMessage + ", currentTime=" + currentTime + '}'; } public RestResult(boolean success, String code, Object data, Object errorMessage) { this.success = success; this.code = code; this.data = data; this.errorMessage = errorMessage; this.currentTime = new Timestamp(new DateTime().getMillis()); } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Object getErrorMessage() { return errorMessage; } public void setErrorMessage(Object errorMessage) { this.errorMessage = errorMessage; } public Timestamp getCurrentTime() { return currentTime; } public void setCurrentTime(Timestamp currentTime) { this.currentTime = currentTime; } }
将返回数据包装成Rest风格
实现ResponseBodyAdvice<T>
package com.futao.springmvcdemo.foundation;import com.alibaba.fastjson.JSONObject;import com.futao.springmvcdemo.model.system.RestResult;import org.apache.commons.lang3.StringUtils;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.servlet.mvc.method.annotation.ResponseBodyAdvice;/** * @author futao * Created on 2018/9/22-20:24. * 返回Rest风格的数据 */@ControllerAdvice(basePackages = "com.futao.springmvcdemo.controller")public class RestResultWrapper implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { RestResult result = new RestResult(true, "0", body, null); return JSONObject.toJSON(result); } }
请求测试
@GetMapping("get") public User get() { User user = new User(); user.setUsername("NiuBist"); user.setId("123"); user.setAge("18"); user.setEmail("12312@qq.com"); user.setMobile("12312321312"); user.setAddress("浙江省杭州市"); return user; }
结果:
请求结果
二,统一异常处理,返回统一异常数据结构
定义一个类来存放所以的异常提示信息,便于管理
package com.futao.springmvcdemo.model.entity.constvar;/** * @author futao * Created on 2018/9/21-15:29. * 错误提示集合类 * 错误码构成: 01程序员编号 * 001该程序员定义的错误码 * 后面再跟上错误信息 */public final class ErrorMessage { public static final String SYSTEM_EXCEPTION = "系统繁忙,请稍后再试"; public static final String NOT_LOGIN = "01001_您还未登陆或者登陆已超时,请重新登陆"; public static final String MOBILE_ALREADY_REGISTER = "01002_该手机号已经被注册了"; public static final String LOGIC_EXCEPTION = "01003_对不起,你是真的没有我帅"; }
定义逻辑异常类
package com.futao.springmvcdemo.foundation;/** * @author futao * Created on 2018/9/20-15:22. * 业务逻辑异常类 */public class LogicException extends RuntimeException { /** * 异常信息 */ private String errorMsg; /** * 错误码 */ private String code; public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } private LogicException(String errorMsg) { super(errorMsg); this.code = errorMsg.substring(0, 5); this.errorMsg = errorMsg.substring(6); } /** * 抛出逻辑异常 * * @param errorMsg * @return */ public static LogicException le(String errorMsg) { return new LogicException(errorMsg); } }
对异常(包括系统异常与业务逻辑异常)进行统一处理
package com.futao.springmvcdemo.foundation;import com.alibaba.fastjson.JSONObject;import com.futao.springmvcdemo.model.entity.constvar.ErrorMessage;import com.futao.springmvcdemo.model.system.RestResult;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * @author futao * Created on 2018/9/21-15:13. * 异常统一处理, */@ControllerAdvicepublic class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ExceptionHandler(value = Exception.class) @ResponseBody public Object logicExceptionHandler(HttpServletRequest request, Exception e, HttpServletResponse response) { //系统级异常,错误码固定为-1,提示语固定为系统繁忙,请稍后再试 RestResult result = new RestResult(false, "-1", e.getMessage(), ErrorMessage.SYSTEM_EXCEPTION); //如果是业务逻辑异常,返回具体的错误码与提示信息 if (e instanceof LogicException) { LogicException logicException = (LogicException) e; result.setCode(logicException.getCode()); result.setErrorMessage(logicException.getErrorMsg()); } else { //对系统级异常进行日志记录 logger.error("系统异常:" + e.getMessage(), e); } return JSONObject.toJSON(result); } }
测试
package com.futao.springmvcdemo.controller;import com.futao.springmvcdemo.foundation.LogicException;import com.futao.springmvcdemo.model.entity.constvar.ErrorMessage;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @author futao * Created on 2018/9/23-0:28. * 统一异常处理测试接口 */@RequestMapping(path = "exception", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)@RestControllerpublic class ExceptionTestController { /** * 业务逻辑异常 */ @GetMapping(path = "logicException") public void logicException() { throw LogicException.le(ErrorMessage.LOGIC_EXCEPTION); } /** * 系统异常 */ @GetMapping(path = "systemException") public void systemException() { throw new NullPointerException("空指针了,哥门!!!"); } }
逻辑异常
系统级异常
系统级异常
作者:FutaoSmile丶
链接:https://www.jianshu.com/p/9ff254413e9d