实现目标
1、项目对业务错误进行统一管理,每种错误都有固定的编码和文本描述。
例如:status:201, message:用户名不能为空, status:202, message:用户名不能重复。
2、Controller根据情况将错误信息返回给客户端。
当程序判别出业务错误的时候,将错误系统抛出,客户端受到错误信息,例如一下的json格式。
{success:false, status:"201", message:":用户名不能为空"}
实现方案
1、定义统一的错误pojo类。
2、定义系统的业务错误。
3、定义统一的业务异常。
4、定义统一的Conrtroller Response返回基类。
5、定义统一的Controller异常处理,将捕获的业务异常抛出。
具体实现
1、定义统一的错误pojo类(此类建议在共有基础项目中实现,所有微服务项目引用)
public class BusinessError
{
private String status;
private String message;
public BusinessError (String status, String message)
{
this.status = status;
this.message = message;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2、定义系统的业务错误(在具体业务项目中实现,每个微服务都有自己的错误编码和信息维护,建议所有错误都定义在一个文件中,这样好管理,当然错误信息过多,也可以在多个文件中)
public class BusinessErrors
{
public final static BusinessError UsernameEmpty = new BusinessError ("201", "用户名不能为空");
public final static BusinessError UsernameInvalid = new BusinessError ("202", "用户名无效");
public final static BusinessError UsernameRepeated = new BusinessError ("203", "用户名不能重复'");
public final static BusinessError PasswordNotSecurity = new BusinessError ("204", "用户密码安全级别不够");
}
3、定义统一的业务异常(此类建议在共有基础项目中实现,所有微服务项目引用)
public class BusinessException extends Exception
{
/**
*
*/
private static final long serialVersionUID = -8909479486537734468L;
private String status;
private String message;
public BusinessException (BusinessError error)
{
if (error == null)
{
throw new IllegalArgumentException("Initalize BusinessException Error, Argument 'error' is null");
}
this.setStatus(error.getStatus());
this.setMessage(error.getMessage());
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
我们一般在业务层进行业务计算的时候,会检测到一些业务错误,需要将业务错误转化为异常,抛出去。
例如
if(StringUtils.IsEmpty(user.getUsername())){
throw new BusinessException(BusinessErrors.UsernameEmpty);
}
4、定义统一的Conrtroller Response返回基类(此类建议在共有基础项目中实现,所有微服务项目引用)
public class ResponseBase
{
boolean success;
String status;
String message;
public ResponseBase (){
this.success = true;
this.status = "200";
this.message = "";
}
public void setError(JError error)
{
this.success = false;
this.status = error.getStatus();
this.message = error.getMessage();
}
public void setError(JException ept)
{
this.success = false;
this.status = ept.getStatus();
this.message = ept.getMessage();
}
}
this.success = true;
this.status = "200";
this.message = "";
表示返回信息是成功的,无错误(错误编码不能是200,因为200代表正确)。
此类的目的就是将错误或异常转化为抛出的Response
ResponseBase不仅仅是错误信息的返回类,同样也是正常信息的基类,例如Controller返回用户信息
//返回用户信息Response
public class UserInfoResponse extends ResponseBase
{
public UserInfoResponse(){
super();
}
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
//处理获取用户信息的Controller
@ApiOperation(value="根据用户名获取用户信息", httpMethod="GET")
@RequestMapping(value = "/{username}", method = RequestMethod.GET)
public UserInfoResponse findbyUsername(@PathVariable(name = "username") String username)
{
UserInfoResponse response = new UserInfoResponse();
if (StringUtils.isEmpty(username))
{
response.setError(BusinessErrors.UsernameEmpty);
}
else
{
User user = UserService.findByUsername(username);
if (user == null)
{
response.setError(BusinessErrors.UsernameInvalid);
}
else
{
response.setUser(user);
}
}
return response;
}
5、统一的Controller异常处理,将捕获的业务异常抛出。
@ControllerAdvice
public class ControllerHandler {
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseBase BusinessException(BusinessException ept)
{
ResponseBase rps = new ResponseBase ();
rps.setError(ept);
return rps;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseBase handlerException(Exception ept)
{
ResponseBase rps = new ResponseBase ("500", "系统错误:" + ept.getMessage());
return rps;
}
}