美文网首页
深入学习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