全局异常处理机制
我们应该做一个统一错误响应,返回给前端的应该是意义明确的json结构
{
code:10001
message:xxxx
request:GET url
}
message:是错误响应的具体消息
code:代表的是错误类型编码
request:表示当前接口访问的url
1.GlobalExceptionAdvice
//接收项目抛出的异常
@ControllerAdvice //特定注解实现加入spring容器
public class GlibalExceptionAdvice{
//注入配置类,供下文中代码获取到其中的message信息
@Autowired
private ExceptionCodeConfiguration codeCongiguration;
@ExceptionHandler(value=Exception.class)//通过指定value处理通用的异常(未知异常)
@ResponseBody //打上这个注解,数据才可以返回到前端
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR) //设置指定当前返回的错误状态码:500
//HttpServletRequest这个对象获取当前访问接口的url
public UnifyResponse hadleException(HttpServletRequest req,Exception e){
String requestUrl = req.getRequestURI();
String method = req.getMethod();
System.out.println(e); //打印一下异常,方便进行后端开发时调试
UnifyResponse message = new UnifyResponse(999,'服务器异常',method +' '+ requestUrl);
return message;
}
@ExceptionHandler(value=HttpException.class) //只监听http异常(已知异常)
public RespomseEntity hadlehttpException(HttpServletRequest req,HttpException e){
String requestUrl = req.getRequestURI();
String method = req.getMethod();
/*
*HttpHeaders是Spring自带的起到的作用是可以设置返回的类型
*以前为什么我们没有设置,现在设置了那?
*因为我们使用了@ResponseBody注解,他自动帮我们进行了设置,现在没有使用我们需要自己进行设置
*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); //因为我们是API,所以要将类型设置为JSON
UnifyResponse message = new UnifyResponse(e.getCode(),codeConfiguration.getMessage(e.getCode),method +' '+ requestUrl);
/*
*HttpStatus是Spring自带的起到的作用是可以灵活的根据HttpException异常类获取状态码
*以前为什么我们没有设置,现在设置了那?
*因为我们使用了@ResponseBody注解,他自动帮我们进行了设置,现在没有使用我们需要自己进行设置
*/
HttpStatus httpstatus = HttpStatus.resolve(e.getHttpStatusCode());
//RespomseEntity可以在里面设置很多属性,这种粒度的控制比上面直接return一个对象会更加
//RespomseEntity返回成什么样的类型就将其指定为什么类型泛型
RespomseEntity<UnifyResponse> r = new RespomseEntity<>(message,headers,httpstatus)
return r;
}
}
2.HttpException
import lombdo
//HttpException代表了一类和http相关的异常
@get
public class HttpException extends RuntimeException{
protected Integer code;
//http状态码
protected Integer httpStatusCode=500;
}
3.NotFoundException
public class NotFoundException extends HttpException{
public NotFoundException(int code){
this.httpStatusCode=404; //覆盖父类的状态码
this.code=code; //接收用户传入的code
}
}
4.ForbiddenException
public class ForbiddenException extends HttpException{
public ForbiddenException(int code){
this.code = code;
this.httpStatusCode = 403; //权限不足
}
}
5.UnifyResponse
//统一错误响应格式
import lombad
@get
public calss UnifyResponse{
private int code;
private String message;
private String request;
public UbifyRequest(int code,String message,String request){
this.code = code;
this.message = mesage;
this.request = request;
}
}
6.exception-code.properties
//动态将异常信息message从配置中获取传入代码中,避免硬编码写message
lin.codes[10001] = 通用参数错误 //配置文件不要加单引号,双引号,spring会自动添加的
lin.codes[10000] = 通用异常
7.ExceptionCodeConfiguration
/*因为我们的需求是动态的加载配置中的异常状态码信息,
*我们没法使用@Value这种硬编码的方式,为了实现动态获取,
*我们需要维护一个配置文件的配置类
*/
//如何将一个类和配置文件进行对应,spring已经实现好了,添加@PropertySource注解即可实现配置文件和配置类进行对应
@PropertySource(value = "classpath:config/excepetion-code.properties") // classpath:类路径下
/*
*怎么使配置文件中的配置项和配置类中字段进行一一对应,spring已经实现好了,
*通过@ConfigurationProperties注解的prefix定义配置项的前缀,就可实现配
*置项和字段对应
*/
@ConfigurationProperties(prefix = "lin")
@Component//注入容器,才能受springBoot的同一管理
public class EceptionCodeonfiguration{
private Map<Integer,String> codes = new HashMap<>();
public String getMessage(int code){
String message = codes.get(code);
return message;
}
}
根据目录结构自动生成路由前缀
1.BannerController
//api接口
@RestController
@RequestMapping("/banner")
public class BannerController{
@Autowired
private ISkill iSkill;
@GetMapping("/tets")
public String test(){
iSkill.r()
}
}
2.AutoPrefixUrlMapping
//RequsetMappingHandlerMapping类就是spring定义的处理带有RequsetMapping注解的collection的
public class AutoPrefixUrlMapping extends RequsetMappingHandlerMapping{
@Override
protected RequestMappingInfo getMappingForMethod(Method method,Class<?> handlerTyoe){ //接收一下
RequestMappingInfo mappingInfo = super.getMappingForMethod(method,handlerType);
if(mappingInfo != null){//不为空我们就进行路由信息的修改
}
return
}
private String getPrefix(Class<?> handlerTyoe){
String packageName = hadleType.getPackage().getName();
return packageName
}
}
3.AutoPrefixConfiguration
//配置类:将AutoPrefixUrlMapping注入到spring容器中
@Component
public class AutoPrefixConfiguration implements WebMvcRegistrations{
@Override
public RequestMappingHandleMapping getRequestMapping{
return new AutoPrefixUrlMapping
}
}