精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringBoot錯(cuò)誤頁(yè)面的原理,你知道嗎?

開(kāi)發(fā) 前端
通過(guò)分析,默認(rèn)情況下springboot容器啟動(dòng)后會(huì)像tomcat容器中注冊(cè)一個(gè)/error的錯(cuò)誤頁(yè),這個(gè)/error又是誰(shuí)呢?

環(huán)境:Springboot3.0.5

錯(cuò)誤消息格式

有如下接口:

@RestController
@RequestMapping("/demo")
public class DemoController {


  @GetMapping("/index")
  public Object index() {
    System.out.println(1 / 0) ;
    return "/demo/index" ;
  }
  
}

當(dāng)訪問(wèn)上面接口后,默認(rèn)情況下Springboot會(huì)返回如下錯(cuò)誤信息:

圖片

當(dāng)請(qǐng)求的Accept是text/html返回的是HTML結(jié)果,當(dāng)Accpet是application/json返回如下:

圖片

后臺(tái)接口會(huì)根據(jù)不同的Accept返回不同的數(shù)據(jù)格式。

錯(cuò)誤處理原理

Springboot在啟動(dòng)過(guò)程中會(huì)執(zhí)行如下處理:

public abstract class AbstractApplicationContext {
  public void refresh() {
    onRefresh();
  }
}

ServletWebServerApplicationContext

public class ServletWebServerApplicationContext {
  protected void onRefresh() {
    super.onRefresh();
    try {
      // 創(chuàng)建web服務(wù)
      createWebServer();
    } catch (Throwable ex) {
      throw new ApplicationContextException("Unable to start web server", ex);
    }
  }
  private void createWebServer() {
    // 這里假設(shè)我們使用的是Tomcat容器,那么這里的factory = TomcatServletWebServerFactory
    this.webServer = factory.getWebServer(getSelfInitializer());
  }
}

TomcatServletWebServerFactory

public class TomcatServletWebServerFactory {
  public WebServer getWebServer(ServletContextInitializer... initializers) {
    // 創(chuàng)建Tomcat實(shí)例
    Tomcat tomcat = new Tomcat();
    // ...
    // 準(zhǔn)備上下文
    prepareContext(tomcat.getHost(), initializers);
    return getTomcatWebServer(tomcat);
  }
  protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
    // 該類繼承自StandardContext類(該類所屬tomcat,每一個(gè)StandardContext代表了一個(gè)webapp)
    TomcatEmbeddedContext context = new TomcatEmbeddedContext();
    // ...
    // 配置上下文
    configureContext(context, initializersToUse);
  }
  // 配置上下文
  protected void configureContext(Context context, ServletContextInitializer[] initializers) {
    // 獲取當(dāng)前Spring容器中配置的ErrorPage,然后注冊(cè)到Tomcat當(dāng)前webapp的上下文中
    // 這里其實(shí)對(duì)應(yīng)的就是web.xml中配置的錯(cuò)誤頁(yè)
    for (ErrorPage errorPage : getErrorPages()) {
      org.apache.tomcat.util.descriptor.web.ErrorPage tomcatErrorPage = new org.apache.tomcat.util.descriptor.web.ErrorPage();
      tomcatErrorPage.setLocation(errorPage.getPath());
      tomcatErrorPage.setErrorCode(errorPage.getStatusCode());
      tomcatErrorPage.setExceptionType(errorPage.getExceptionName());
      context.addErrorPage(tomcatErrorPage);
    }
  }
}

TomcatServletWebServerFactory類實(shí)現(xiàn)了ErrorPageRegistry接口,有如下方法:

// TomcatServletWebServerFactory繼承自AbstractConfigurableWebServerFactory
// ConfigurableWebServerFactory接口繼承了ErrorPageRegistry接口
public abstract class AbstractConfigurableWebServerFactory implements ConfigurableWebServerFactory {
  public void addErrorPages(ErrorPage... errorPages) {
    this.errorPages.addAll(Arrays.asList(errorPages));
  }
}

下面查看上面的addErrorPages方法是如何被調(diào)用的。

在自動(dòng)配置類中導(dǎo)入了下面的類

@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class ServletWebServerFactoryAutoConfiguration {
}
// BeanPostProcessorsRegistrar實(shí)現(xiàn)了ImportBeanDefinitionRegistrar,用來(lái)注冊(cè)Bean
public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    // 注冊(cè)了BeanPostProcessor類ErrorPageRegistrarBeanPostProcessor
    registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", ErrorPageRegistrarBeanPostProcessor.class);
  }
}
public class ErrorPageRegistrarBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 判斷當(dāng)前的Bean是否實(shí)現(xiàn)了ErrorPageRegistry
    if (bean instanceof ErrorPageRegistry errorPageRegistry) {
      postProcessBeforeInitialization(errorPageRegistry);
    }
    return bean;
  }
  private void postProcessBeforeInitialization(ErrorPageRegistry registry) {
    // 遍歷所有的ErrorPageRegistrar,注冊(cè)到當(dāng)前實(shí)現(xiàn)了ErrorPageRegistry接口的Bean中
    // 如上面的TomcatServletWebServerFactory
    for (ErrorPageRegistrar registrar : getRegistrars()) {
      registrar.registerErrorPages(registry);
    }
  }
  private Collection<ErrorPageRegistrar> getRegistrars() {
    if (this.registrars == null) {
      // 獲取容器中所有的ErrorPageRegistrar Bean對(duì)象
      this.registrars = new ArrayList<>(this.beanFactory.getBeansOfType(ErrorPageRegistrar.class, false, false).values());
      this.registrars.sort(AnnotationAwareOrderComparator.INSTANCE);
      this.registrars = Collections.unmodifiableList(this.registrars);
    }
    return this.registrars;
  }
}

接下來(lái)就是從容器中獲取ErrorPageRegistrar,然后注冊(cè)到ErrorPageRegistry中。

在如下自動(dòng)配置類中定義了一個(gè)默認(rèn)的錯(cuò)誤頁(yè)對(duì)象。

public class ErrorMvcAutoConfiguration {
  @Bean
  public ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {
    return new ErrorPageCustomizer(this.serverProperties, dispatcherServletPath);
  }
  static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
    // springboot配置文件中的server接口中獲取error配置信息
    private final ServerProperties properties;


    private final DispatcherServletPath dispatcherServletPath;


    protected ErrorPageCustomizer(ServerProperties properties, DispatcherServletPath dispatcherServletPath) {
      this.properties = properties;
      this.dispatcherServletPath = dispatcherServletPath;
    }


    @Override
    public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
      // 獲取server.error.path配置屬性
      ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));
      errorPageRegistry.addErrorPages(errorPage);
    }
  }
}
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
  @NestedConfigurationProperty
  private final ErrorProperties error = new ErrorProperties();
}
public class ErrorProperties {
  // 讀取error.path配置,如果沒(méi)有配置,則默認(rèn)是/error
  @Value("${error.path:/error}")
  private String path = "/error";
}

通過(guò)上面的分析,默認(rèn)情況下springboot容器啟動(dòng)后會(huì)像tomcat容器中注冊(cè)一個(gè)/error的錯(cuò)誤頁(yè),這個(gè)/error又是誰(shuí)呢?

默認(rèn)錯(cuò)誤Controller

在默認(rèn)的錯(cuò)誤頁(yè)自動(dòng)配置中:

public class ErrorMvcAutoConfiguration {
  @Bean
  @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
  public DefaultErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes();
  }


  // 該Controller就是默認(rèn)的/error錯(cuò)誤跳轉(zhuǎn)的類
  @Bean
  @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
  public BasicErrorController basicErrorController(ErrorAttributes errorAttributes, ObjectProvider<ErrorViewResolver> errorViewResolvers) {
    return new BasicErrorController(errorAttributes, this.serverProperties.getError(),errorViewResolvers.orderedStream().toList());
  }
}
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
  // 當(dāng)請(qǐng)求的Accept=text/html時(shí)調(diào)用該方法
  @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
  public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
    // ...
  }
  // 當(dāng)請(qǐng)求的Accept=application/json時(shí)調(diào)用該方法
  @RequestMapping
  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    HttpStatus status = getStatus(request);
    if (status == HttpStatus.NO_CONTENT) {
      return new ResponseEntity<>(status);
    }
    Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
    return new ResponseEntity<>(body, status);
  }
}

以上就是當(dāng)springboot默認(rèn)情況下發(fā)生錯(cuò)誤時(shí)的執(zhí)行輸出原理。

責(zé)任編輯:武曉燕 來(lái)源: 實(shí)戰(zhàn)案例錦集
相關(guān)推薦

2024-02-19 00:00:00

Console函數(shù)鏈接庫(kù)

2024-02-26 08:19:00

WebSpring容器

2024-04-07 00:00:00

ESlint命令變量

2024-05-28 09:12:10

2023-04-26 10:21:04

2024-04-30 09:02:48

2023-12-20 08:23:53

NIO組件非阻塞

2023-12-12 08:41:01

2020-02-20 08:30:49

OSPF網(wǎng)絡(luò)協(xié)議路由協(xié)議

2022-11-28 00:04:17

2024-07-08 00:00:01

多線程ThreadC#

2022-11-04 14:16:05

2023-01-13 17:02:10

操作系統(tǒng)鴻蒙

2023-03-21 07:39:51

CentOS掛載硬盤(pán)

2022-09-29 15:32:58

云計(jì)算計(jì)算模式

2021-04-20 23:16:06

SparkSQL語(yǔ)法

2021-10-14 06:52:47

算法校驗(yàn)碼結(jié)構(gòu)

2024-01-15 12:16:37

2025-02-18 08:11:17

2025-06-16 09:36:18

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

免费看a在线观看| 国产专区第一页| 6080成人| 日韩欧美成人区| 一本久道久久综合狠狠爱亚洲精品| 91在线视频国产| 国语自产精品视频在线看8查询8| 国产视频在线一区二区| 17c国产在线| 欧美aa在线| 日韩美女视频一区二区| 国产一区二区三区奇米久涩| 中文字幕精品一区二| 2023国产精品久久久精品双| 亚洲国产精品字幕| av污在线观看| 在线中文字幕播放| 亚洲精品国产无套在线观| 久久久久网址| 精品久久久无码中文字幕| 香蕉久久久久久久av网站| 久久色免费在线视频| 久久一区二区电影| 国产视频一区二| 欧洲色大大久久| 大陆av在线播放| 精品国产99久久久久久| 2021国产精品久久精品| 91青青草免费在线看| 欧美成人一区二区视频| 亚洲国产激情| 欧美精品午夜视频| 91无套直看片红桃在线观看| 日韩av不卡一区| 4438x亚洲最大成人网| 精品国产成人av在线免| free性m.freesex欧美| 亚洲精品国产成人久久av盗摄| 日韩精品资源| 国内在线免费高清视频| 99re在线视频这里只有精品| 国产精品日韩欧美一区二区| av av片在线看| 精品一区二区三区免费视频| 国产精品永久免费观看| 中文字幕日本视频| 麻豆精品网站| 国产97人人超碰caoprom| 午夜精品三级久久久有码| 欧美va天堂在线| 欧美成人黑人xx视频免费观看| 国产精品免费人成网站酒店| 亚洲欧洲美洲一区二区三区| 精品国偷自产在线视频| 激情五月激情综合| 国产韩国精品一区二区三区| 久久精品最新地址| 永久看片925tv| 欧美日韩视频一区二区三区| 欧美极品欧美精品欧美视频 | 国产成人精品免费久久久久| aaa人片在线| 亚洲人体偷拍| 精品自在线视频| 青青操在线视频观看| 一区二区国产在线| 日韩一区二区av| 国产精品久久久视频| 国产精品一区二区99| 日韩av中文字幕在线免费观看| 极品白嫩的小少妇| 给我免费播放日韩视频| 精品福利一区二区三区免费视频| 日日夜夜精品视频免费观看| 国产高清日韩| 欧美日韩在线一区| 一卡二卡三卡视频| 国产夫妻在线| 欧美日韩一区免费| 日本精品免费在线观看| 亚洲天堂资源| 色88888久久久久久影院野外| 无码人妻丰满熟妇区毛片| 精品成人av| 欧美视频一区二区| 不用播放器的免费av| 精品国产亚洲日本| 91精品国产一区二区| 成人高清在线观看视频| 盗摄牛牛av影视一区二区| 亚洲成人精品久久久| 亚洲国产无码精品| 欧美日韩中文一区二区| 中文字幕日韩电影| 国产美女福利视频| 合欧美一区二区三区| 9.1国产丝袜在线观看| 三级视频在线观看| 日本欧美一区二区三区乱码| 91精品国产综合久久香蕉的用户体验 | 亚洲三级免费电影| 日韩视频在线视频| 性欧美hd调教| 这里只有精品免费| zjzjzjzjzj亚洲女人| 免费成人结看片| 日日狠狠久久偷偷四色综合免费| 久久国产在线观看| 影院欧美亚洲| 国产激情视频一区| www.看毛片| 久久伊人中文字幕| 一区二区成人国产精品| bl在线肉h视频大尺度| 日本高清不卡视频| 人妻换人妻仑乱| 香蕉一区二区| 粗暴蹂躏中文一区二区三区| 午夜毛片在线观看| 美女视频黄久久| 美女亚洲精品| 污视频网站在线免费| 精品动漫一区二区三区| 色综合色综合色综合色综合| jazzjazz国产精品久久| 最近2019年好看中文字幕视频 | 91免费视频网站在线观看| 高清欧美日韩| 日韩电影第一页| 国产一区二区三区在线视频观看| 免费国产自线拍一欧美视频| 亚洲自拍av在线| yw视频在线观看| 欧美日韩国产一区在线| 污免费在线观看| 凹凸成人精品亚洲精品密奴| 午夜免费日韩视频| 国产又爽又黄免费软件| 欧美高清在线精品一区| 亚洲午夜精品久久久久久人妖| 95精品视频| 亚洲视频电影图片偷拍一区| 精品亚洲永久免费| 另类欧美日韩国产在线| 欧美日本亚洲| 6699嫩草久久久精品影院| 欧美一区二区日韩| 女教师淫辱の教室蜜臀av软件| av成人黄色| 精选一区二区三区四区五区| 在线免费观看的av| 91.com视频| 国产精品久久免费观看| 国产欧美午夜| 精品麻豆av| 丝袜美腿av在线| 欧美一二三四区在线| 69夜色精品国产69乱| 蜜臀精品久久久久久蜜臀| 久久久久久久久一区| 牛牛精品在线视频| 欧美色图在线观看| 女人黄色一级片| 人人狠狠综合久久亚洲| 欧美日韩一区在线观看视频| 成人美女大片| 国产一区二区三区精品久久久| 国产情侣自拍av| 91在线小视频| 超碰97人人射妻| 国产欧美日韩| 国产精品久久一区主播| 国产乱子伦三级在线播放| 91精品91久久久中77777| 精品无码国产污污污免费网站| 美女精品一区| 色吧亚洲视频| 色成人综合网| 欧美成人免费全部观看天天性色| 亚洲va韩国va欧美va精四季| youjizz亚洲女人| 免费观看在线综合| 亚洲制服欧美久久| 亚洲免费一区| 久久的精品视频| 东京干手机福利视频| 欧美色播在线播放| 波多野结衣家庭教师在线观看| 韩国一区二区在线观看| 成人免费在线视频播放| 91欧美日韩在线| 7777精品视频| porn视频在线观看| 欧美一区二区三区婷婷月色| 黄色激情视频在线观看| 91美女在线观看| 校园春色 亚洲色图| 综合久久婷婷| 国产精品午夜av在线| 日韩中文视频| 色与欲影视天天看综合网| 天堂av2024| 欧美亚洲免费在线一区| 一区二区在线观看免费视频| 2021久久国产精品不只是精品| gogogo高清免费观看在线视频| 亚洲xxx拳头交| 欧美午夜精品久久久久久蜜| 欧美亚洲综合视频| 国外成人在线播放| av电影在线观看一区二区三区| 日韩欧美国产综合| 6080午夜伦理| 亚洲精品欧美在线| 巨胸大乳www视频免费观看| 国产成人av一区二区三区在线| 免费观看日韩毛片| 国产精品久久占久久| 久久伊人一区| 久久精品九色| 国产精品99蜜臀久久不卡二区| а√天堂在线官网| 亚洲乱亚洲乱妇无码| 6—12呦国产精品| 在线观看91视频| 欧美bbbbbbbbbbbb精品| 亚洲日本电影在线| 中文字幕第4页| 国产99精品视频| 日韩高清第一页| 久久精品三级| 国产911在线观看| 羞羞答答成人影院www| 另类小说综合网| 99久久人爽人人添人人澡| 国产精品精品久久久| 国产传媒在线| 欧美国产乱视频| 毛片在线不卡| 日韩成人中文字幕在线观看| 好吊视频一区二区三区| 5566中文字幕一区二区电影| 波多野结衣高清在线| 五月激情综合婷婷| 动漫精品一区一码二码三码四码| 中文字幕亚洲视频| 亚洲图片另类小说| av毛片久久久久**hd| 亚洲av无日韩毛片久久| 国产一区二区女| 中文字幕丰满乱码| 麻豆91精品视频| 亚洲激情在线观看视频| 丝袜美腿高跟呻吟高潮一区| 成人性免费视频| 国内精品久久久久久久97牛牛 | 一区二区精品视频在线观看| 欧美在线|欧美| 久久久久久久亚洲| 色婷婷av一区二区| 超碰在线免费97| 欧美视频一区二区三区在线观看 | 久久精品天堂| 国产视频一区二区三区在线播放| 亚洲欧美日韩国产| 成人免费观看毛片| 日韩精品久久理论片| 国产日韩一区二区在线观看| 久久久久久久高潮| 日韩视频免费播放| 亚洲黄色成人| 欧美大片在线播放| 亚洲欧美日本国产专区一区| 韩国一区二区av| 日本不卡一区二区三区| 韩国日本美国免费毛片| 热久久久久久久| 在线免费av播放| 大白屁股一区二区视频| 在线播放第一页| 成人av在线影院| 熟女少妇一区二区三区| 亚洲国产精品黑人久久久| а天堂中文在线资源| 国产精品女同一区二区三区| 国产性生活网站| 欧美视频不卡中文| 成人黄色片在线观看| 7878成人国产在线观看| 成人高潮片免费视频| 亚洲国产成人精品女人久久久| 青青久在线视频| 日韩视频在线观看免费| 日本性爱视频在线观看| 羞羞色国产精品| 香蕉视频亚洲一级| 国产日韩欧美黄色| 99精品国产高清一区二区麻豆| 麻豆一区区三区四区产品精品蜜桃| 日韩毛片视频| avav在线播放| 天堂成人免费av电影一区| 奇米影视四色在线| 成人免费高清在线| a天堂中文字幕| 亚洲一区中文日韩| 天堂网一区二区三区| 日韩欧美视频在线| 日韩在线免费播放| 不卡av在线网站| 周于希免费高清在线观看| 成人免费激情视频| 欧美综合精品| 亚洲一区三区在线观看| 六月丁香综合| 人妻精品久久久久中文字幕69| 久久夜色精品国产噜噜av| 国产一级淫片久久久片a级| 亚洲一区二区在线观看视频| 日日骚av一区二区| 日韩一区二区三区av| 欧美日本韩国一区二区| 久久久这里只有精品视频| 福利精品一区| 久久久久久久久久久久久久久久av| 五月精品视频| 午夜激情福利在线| av一二三不卡影片| 亚洲熟女毛茸茸| 色综合久久中文综合久久97 | 午夜在线a亚洲v天堂网2018| 久久久久久久久久影视| 中文字幕+乱码+中文字幕一区| 欧美三级午夜理伦| 精品国产电影一区二区| 黄视频网站在线看| 国产免费成人av| 天堂一区二区三区四区| 日本中文字幕网址| 国产成人福利片| 日韩在线观看视频一区二区| 欧美亚洲动漫制服丝袜| 欧美性孕妇孕交| 高清欧美性猛交xxxx黑人猛交| 国产免费av国片精品草莓男男| 一区二区三区视频| 日韩avvvv在线播放| 国产伦精品一区二区三区妓女| 亚洲一区二区三区免费视频| www.污视频| 欧美成人亚洲成人| 台湾天天综合人成在线| 手机看片日韩国产| 久久se精品一区二区| av男人的天堂av| 欧美日韩精品国产| 亚洲三区在线播放| 欧美亚洲激情视频| 天堂在线精品| 国产精品99久久免费黑人人妻| 国产视频一区二区在线观看| 日韩电影在线观看一区二区| 亚洲午夜未删减在线观看| 欧美成人精品一区二区男人小说| 国产视频一区二区不卡| 亚洲精一区二区三区| yy1111111| 91国产福利在线| 福利视频在线看| 国产精品尤物福利片在线观看| 欧洲激情综合| 亚洲精品手机在线观看| 久久精品一区二区三区不卡| 国产一区二区在线播放视频| 久久国产精品久久久久久| 欧美一级片网址| 黄色一级大片免费| 国产69精品久久久久777| 欧美丰满熟妇bbbbbb| 亚洲黄色免费三级| 三级成人在线| 一区二区三区四区| 顶级嫩模精品视频在线看| 日韩精品成人在线| 亚洲欧美日韩爽爽影院| 国产原创一区| www成人免费| 97精品国产露脸对白| 无码一区二区三区| 国产一区二区动漫| 6080亚洲理论片在线观看| 少妇av一区二区三区无码| 久久精子c满五个校花| 国产欧美一级片| 欧美亚洲国产日本| 成人免费看片39| 国内自拍偷拍视频| 91国产丝袜在线播放| 91cn在线观看| 欧洲精品码一区二区三区免费看|