最近写代码的时候,遇到一个问题:
框架遇到异常后会返回一个 JSON 格式的数据,如:{"msg":"id不存在","code":"1001"}
为了方便前端统一处理,正确返回的 Controller 返回也要是这个格式。但要考虑各种情况的异常信息,Service 类就也要放回这个格式的类。
问题示例代码如下:
Controller 类
package blog.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import blog.service.UserService;
/**
* 用户信息管理
* @author ConstXiong
* @date 2020-04-26 20:49:02
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 保存用户电话
* @param id
* @param tel
* @return
*/
@RequestMapping("saveUserTel")
@ResponseBody
public Map<String, Object> saveUserTel(Integer id, String tel) {
return userService.saveUserTel(id, tel);
}
}
Service 类
package blog.service;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* 用户信息管理服务类
* @author ConstXiong
* @date 2020-04-26 10:52:58
*/
@Service
public class UserService {
/**
* 保存用户电话信息
* @param id
* @param tel
*/
public Map<String, Object> saveUserTel(int id, String tel) {
Map<String, Object> result = new HashMap<String, Object>();
//校验id是否存在
if (id < 1) {
result.put("code", "1001");//假设 id 不能为空的 错误码是1001
result.put("msg", "id不存在");
return result;
}
if (StringUtils.isEmpty(tel)) {
result.put("code", "1002");//假设 tel 为空的 错误码是1002
result.put("msg", "电话不能为空");
return result;
}
if (tel.length() > 11) {
result.put("code", "1003");//假设 tel 长度超过11 错误码1003
result.put("msg", "电话号码超长");
return result;
}
result.put("code", "0");//保存成功的错误
result.put("msg", "保存成功");
return result;
}
}
请求url返回如下:
http://localhost:8081/blog/user/saveUserTel.do?id=-1&tel=13888888888
{"msg":"id不存在","code":"1001"}
http://localhost:8081/blog/user/saveUserTel.do?id=1&tel=138888888888
{"msg":"电话号码超长","code":"1003"}
http://localhost:8081/blog/user/saveUserTel.do?id=1&tel=13888888888
{"msg":"保存成功","code":"0"}
Service 类中存在这 2 个问题:
@ControllerAdvice 是 spring web 中的一个注解,作用是对 Controller 进行增加,我们可以使用这个注解进行全局的异常处理。
通过 @ControllerAdvice 进行整改,是一种方式。
代码如下:
1、新增自定义异常
package blog.exception;
/**
* 自定义异常
* @author ConstXiong
* @date 2020-04-27 10:19:15
*/
public class CustomException extends RuntimeException {
private static final long serialVersionUID = 675600741944661752L;
private String code;
public CustomException(String code, String msg) {
super(msg);
this.code = code;
}
public String getCode() {
return code;
}
}
2、新增自定义异常处理类
package blog.handler;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import blog.exception.CustomException;
/**
* 全局异常处理,捕获所有Controller中抛出的异常。
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomException.class)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public Map<String, Object> handleCustomException (CustomException e) throws Exception {
Map<String, Object> error = new HashMap<String, Object>();
error.put("code", e.getCode());
error.put("msg", e.getMessage());
return error;
}
}
3、新增信息校验类 Checker
package blog.service;
import org.springframework.util.StringUtils;
import blog.exception.CustomException;
/**
* 信息校验类
* @author ConstXiong
* @date 2020-04-26 20:28:41
*/
public class Checker {
/**
* 必须大于等于某值
* @param num
* @param min
* @param errCode
* @param errMsg
*/
public static void mustLargerThan(int num, int min, String errCode, String errMsg) {
if (num < min) {
throw new CustomException(errCode, errMsg);
}
}
/**
* 不能为空
* @param str
* @param errCode
* @param errMsg
*/
public static void mustNotEmpy(String str, String errCode, String errMsg) {
if (StringUtils.isEmpty(str)) {
throw new CustomException(errCode, errMsg);
}
}
/**
* 字符串长度不能超过
* @param str
* @param len
* @param errCode
* @param errMsg
*/
public static void lengthNoLongerThan(String str, int len, String errCode, String errMsg) {
if (str.length() > len) {
throw new CustomException(errCode, errMsg);
}
}
}
4、整改 Controller 和 Service 类的代码
package blog.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import blog.service.UserService;
/**
* 用户信息管理
* @author ConstXiong
* @date 2020-04-26 20:49:02
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 保存用户电话
* @param id
* @param tel
* @return
*/
@RequestMapping("saveUserTel")
@ResponseBody
public Map<String, Object> saveUserTel(Integer id, String tel) {
userService.saveUserTel(id, tel);
//success 可以放到常量类里定义
Map<String, Object> success = new HashMap<String, Object>();
success.put("code", "0");
success.put("msg", "保存成功");
return success;
}
}
package blog.service;
import org.springframework.stereotype.Service;
/**
* 用户信息管理服务类
* @author ConstXiong
* @date 2020-04-26 10:52:58
*/
@Service
public class UserService {
/**
* 保存用户电话信息
* @param id
* @param tel
*/
public boolean saveUserTel(int id, String tel) {
Checker.mustLargerThan(id, 0, "1001", "id不存在");
Checker.mustNotEmpy(tel, "1002", "电话不能为空");
Checker.lengthNoLongerThan(tel, 11, "1003", "电话号码超长");
return true;
}
}
整改完之后,请求 url 返回与之前相同。
总结一下这样处理的好处:
PS:
ConstXiong 备案号:苏ICP备16009629号-3