美文网首页
深入学习java笔记-6.SpringBoot2.1之全局异常

深入学习java笔记-6.SpringBoot2.1之全局异常

作者: 笨鸡 | 来源:发表于2019-05-08 15:57 被阅读0次
    MyException.java
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    public class MyException extends RuntimeException {
        private Integer code;//异常码
    
        public MyException(String msg) {
            super(msg);
        }
    
        public MyException(Integer code, String msg) {
            super(msg);
            this.code = code;
        }
    
    }
    
    Result.java
    package com.ctgu.springstart.util;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Result implements Serializable {
    
        private Integer code;
    
        private String message;
        
        private Object data;
    
    }
    
    ResultEnum.java
    package com.ctgu.springstart.util;
    
    public enum ResultEnum {
    
        SUCCESS(200, "成功"),
    
        FAIL(100, "失败"),
    
        EXCEPTION(500, "系统异常"),
    
        UNLOGIN(201, "未登录");
    
        private Integer code;
    
        private String msg;
    
        ResultEnum(Integer code, String msg) {
            this.code = code;
            this.msg = 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;
        }
    }
    
    GlobalControllerAdvice.java
    package com.ctgu.springstart.exception;
    
    import com.ctgu.springstart.util.Result;
    import com.ctgu.springstart.util.ResultEnum;
    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 org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    
    @ControllerAdvice
    public class GlobalControllerAdvice {
    
        private static final Logger LOG = LoggerFactory.getLogger(GlobalControllerAdvice.class);
    
        @ExceptionHandler(value = Exception.class)
        @ResponseBody
        public Result defaultException(HttpServletRequest request, Exception e){
            LOG.error("url:{},msg:{}", request.getRequestURL(), e.getMessage());
            return Result.builder()
                    .code(ResultEnum.EXCEPTION.getCode())
                    .message(ResultEnum.EXCEPTION.getMsg())
                    .build();
        }
    
        @ExceptionHandler(value = MyException.class)
        @ResponseBody
        public Object myException(HttpServletRequest request,MyException e){
            Integer code=e.getCode();
            String message=e.getMessage();
    
            LOG.error("define url:{},define msg:{}", request.getRequestURL(), e.getMessage());
            if(e.getCode()==null && e.getMessage() == null){
                ModelAndView modelAndView = new ModelAndView();
                modelAndView.setViewName("error/error.html");
                modelAndView.addObject("msg", e.getMessage());
                return modelAndView;
            }
            if (e.getCode()==null){
                code=ResultEnum.EXCEPTION.getCode();
            }
            if (e.getMessage()==null){
                message=ResultEnum.EXCEPTION.getMsg();
            }
            return Result.builder()
                    .code(code)
                    .message(message)
                    .build();
        }
    }
    
    MyErrorViewResolver.java
    public class MyErrorViewResolver implements ErrorViewResolver, Ordered {
    
        private static final Map<Series, String> SERIES_VIEWS;
        private ApplicationContext applicationContext;
        private ResourceProperties resourceProperties;
        private TemplateAvailabilityProviders templateAvailabilityProviders;
        private int order = 2147483647;
    
        public MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) {
            Assert.notNull(applicationContext, "ApplicationContext must not be null");
            Assert.notNull(resourceProperties, "ResourceProperties must not be null");
            this.applicationContext = applicationContext;
            this.resourceProperties = resourceProperties;
            this.templateAvailabilityProviders = new TemplateAvailabilityProviders(applicationContext);
        }
    
        MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties, TemplateAvailabilityProviders templateAvailabilityProviders) {
            Assert.notNull(applicationContext, "ApplicationContext must not be null");
            Assert.notNull(resourceProperties, "ResourceProperties must not be null");
            this.applicationContext = applicationContext;
            this.resourceProperties = resourceProperties;
            this.templateAvailabilityProviders = templateAvailabilityProviders;
        }
    
        public int getOrder() {
            return this.order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    
        static {
            Map<Series, String> views = new EnumMap(Series.class);
            views.put(Series.CLIENT_ERROR, "4xx");
            views.put(Series.SERVER_ERROR, "5xx");
            SERIES_VIEWS = Collections.unmodifiableMap(views);
        }
    
        @Override
        public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
            //status状态码
            ModelAndView modelAndView = resolve(String.valueOf(status), model);
    
            //由于状态码很多,在上面的代码中可以看到添加了4xx,5xx这样的状态码。意思就是找不到可用的404,401这样的文件,就使用4xx这个文件。
            if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
                modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
            }
            return modelAndView;
        }
    
        private ModelAndView resolve(String viewName, Map<String, Object> model) {
            //默认SpringBoot寻找一个页面文件,位于error/viewName,而这个viewName就是状态码。
            String errorViewName = "error/" + viewName;
    
            //如果模板引擎解析成功就是用这个地址:error/404
            TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
                    .getProvider(errorViewName, this.applicationContext);
            if (provider != null) {
                //返回解析后的视图地址
                return new ModelAndView(errorViewName, model);
            }
            //如果模板引擎不可用,就咋静态资源文件下寻找对应的页面error/404
            return resolveResource(errorViewName, model);
        }
    
        //寻找静态资源里的错误页面
        private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
            for (String location : this.resourceProperties.getStaticLocations()) {
                try {
                    Resource resource = this.applicationContext.getResource(location);
                    resource = resource.createRelative(viewName + ".html");
                    //如果存在viewName.html文件就会返回一个ModelAndView
                    if (resource.exists()) {
                        return new ModelAndView(new HtmlResourceView(resource), model);
                    }
                } catch (Exception ex) {
                }
            }
            return null;
        }
    
        private static class HtmlResourceView implements View {
            private Resource resource;
    
            HtmlResourceView(Resource resource) {
                this.resource = resource;
            }
    
            public String getContentType() {
                return "text/html";
            }
    
            public void render(Map<String, ?> model, HttpServletRequest request,
                               HttpServletResponse response) throws Exception {
                response.setContentType(this.getContentType());
                FileCopyUtils.copy(this.resource.getInputStream(), response.getOutputStream());
            }
        }
    }
    
    CustomErrorType.java
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class CustomErrorType {
    
        private Integer statusValue;
    
        private String message;
    
    }
    
    ExceptionController.java
    @RestController
    public class ExceptionController{
    
        @RequestMapping("/testExp")
        public Object testExp(){
            int b = 1 / 0;
            return new User(111, "alex",
                    15, "1234567", "123@qq.com");
        }
    
        @RequestMapping("/testExpPage")
        public Object testExpPage(){
    //        throw  new MyException(501, "my ext异常");
            throw  new MyException();
        }
    }
    

    相关文章

      网友评论

          本文标题:深入学习java笔记-6.SpringBoot2.1之全局异常

          本文链接:https://www.haomeiwen.com/subject/uhxvoqtx.html