成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring Boot整合jsp后必須通過spring-boot:run方式啟動(dòng)?

roundstones / 800人閱讀

摘要:為什么整合后必須通過方式啟動(dòng)背景在整合這篇文章中,我們用了兩種啟動(dòng)方式方法啟動(dòng)測(cè)試發(fā)現(xiàn),通過啟動(dòng)能夠正常渲染頁面,而通過方法啟動(dòng)無法渲染,本文分析下原因。通過來啟動(dòng)對(duì)應(yīng)的服務(wù)器。

為什么整合jsp后必須通過spring-boot:run方式啟動(dòng)? 背景

在Spring Boot - 整合Jsp/FreeMarker這篇文章中,我們用了兩種啟動(dòng)方式

mvn clean spring-boot:run

main方法啟動(dòng)
測(cè)試發(fā)現(xiàn),通過maven啟動(dòng)能夠正常渲染jsp頁面,而通過main方法啟動(dòng)無法渲染,本文分析下原因。

分析

我們代碼沒有調(diào)整,只是啟動(dòng)方式不同,那么懷疑是classpath不一致!

mvn啟動(dòng)classpath

/Users/wanye/Code/springboot/target/classes/
/Users/wanye/.m2/repository/ch/qos/logback/logback-classic/1.1.9/logback-classic-1.1.9.jar
/Users/wanye/.m2/repository/ch/qos/logback/logback-core/1.1.9/logback-core-1.1.9.jar
/Users/wanye/.m2/repository/com/fasterxml/classmate/1.3.3/classmate-1.3.3.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.8.6/jackson-core-2.8.6.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.8.6/jackson-databind-2.8.6.jar
/Users/wanye/.m2/repository/javax/servlet/jstl/1.2/jstl-1.2.jar
/Users/wanye/.m2/repository/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/8.5.11/tomcat-embed-core-8.5.11.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/8.5.11/tomcat-embed-el-8.5.11.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-jasper/8.5.11/tomcat-embed-jasper-8.5.11.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/8.5.11/tomcat-embed-websocket-8.5.11.jar
/Users/wanye/.m2/repository/org/hibernate/hibernate-validator/5.3.4.Final/hibernate-validator-5.3.4.Final.jar
/Users/wanye/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar
/Users/wanye/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.22/jcl-over-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/jul-to-slf4j/1.7.22/jul-to-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.22/log4j-over-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/slf4j-api/1.7.22/slf4j-api-1.7.22.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.1.RELEASE/spring-boot-autoconfigure-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.5.1.RELEASE/spring-boot-starter-logging-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/1.5.1.RELEASE/spring-boot-starter-tomcat-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-web/1.5.1.RELEASE/spring-boot-starter-web-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.1.RELEASE/spring-boot-starter-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot/1.5.1.RELEASE/spring-boot-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-aop/4.3.6.RELEASE/spring-aop-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-beans/4.3.6.RELEASE/spring-beans-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-context/4.3.6.RELEASE/spring-context-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-core/4.3.6.RELEASE/spring-core-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-expression/4.3.6.RELEASE/spring-expression-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-web/4.3.6.RELEASE/spring-web-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-webmvc/4.3.6.RELEASE/spring-webmvc-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar

Main啟動(dòng)classpath

/Users/wanye/Code/springboot/target/classes/
/Users/wanye/.m2/repository/ch/qos/logback/logback-classic/1.1.9/logback-classic-1.1.9.jar
/Users/wanye/.m2/repository/ch/qos/logback/logback-core/1.1.9/logback-core-1.1.9.jar
/Users/wanye/.m2/repository/com/fasterxml/classmate/1.3.3/classmate-1.3.3.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.8.6/jackson-core-2.8.6.jar
/Users/wanye/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.8.6/jackson-databind-2.8.6.jar
/Users/wanye/.m2/repository/javax/servlet/jstl/1.2/jstl-1.2.jar
/Users/wanye/.m2/repository/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/8.5.11/tomcat-embed-core-8.5.11.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/8.5.11/tomcat-embed-el-8.5.11.jar
/Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/8.5.11/tomcat-embed-websocket-8.5.11.jar
/Users/wanye/.m2/repository/org/hibernate/hibernate-validator/5.3.4.Final/hibernate-validator-5.3.4.Final.jar
/Users/wanye/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar
/Users/wanye/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.22/jcl-over-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/jul-to-slf4j/1.7.22/jul-to-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.22/log4j-over-slf4j-1.7.22.jar
/Users/wanye/.m2/repository/org/slf4j/slf4j-api/1.7.22/slf4j-api-1.7.22.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.1.RELEASE/spring-boot-autoconfigure-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.5.1.RELEASE/spring-boot-starter-logging-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/1.5.1.RELEASE/spring-boot-starter-tomcat-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter-web/1.5.1.RELEASE/spring-boot-starter-web-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.1.RELEASE/spring-boot-starter-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/boot/spring-boot/1.5.1.RELEASE/spring-boot-1.5.1.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-aop/4.3.6.RELEASE/spring-aop-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-beans/4.3.6.RELEASE/spring-beans-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-context/4.3.6.RELEASE/spring-context-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-core/4.3.6.RELEASE/spring-core-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-expression/4.3.6.RELEASE/spring-expression-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-web/4.3.6.RELEASE/spring-web-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/springframework/spring-webmvc/4.3.6.RELEASE/spring-webmvc-4.3.6.RELEASE.jar
/Users/wanye/.m2/repository/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar

對(duì)比

192:~ wanye$ diff Desktop/mainsort Desktop/mvnsort
12a13
> /Users/wanye/.m2/repository/org/apache/tomcat/embed/tomcat-embed-jasper/8.5.11/tomcat-embed-jasper-8.5.11.jar

對(duì)比后發(fā)現(xiàn),通過main啟動(dòng)后classpath缺少tomcat-embed-jasper.jar;定位到這里,我們就可以解決這個(gè)問題了。

解決方法:去掉將pom.xml中tomcat-embed-jasper依賴provided,依賴調(diào)整如下


    org.apache.tomcat.embed
    tomcat-embed-jasper
    
還原現(xiàn)場(chǎng),分析Spring Boot啟動(dòng)流程

在IDE里,直接運(yùn)行的main函數(shù):

@SpringBootApplication
public class Start {
    public static void main(String[] args) {
        SpringApplication.run(Start.class, args);
    }
}
Embead Tomcat的Servlet加載流程

判斷是否在web環(huán)境,略,大家自己查閱相關(guān)資料,不是本文重點(diǎn)。

spring boot通過TomcatEmbeddedServletContainerFactory來啟動(dòng)對(duì)應(yīng)的web服務(wù)器。

//TomcatEmbeddedServletContainerFactory
    @Override
    public EmbeddedServletContainer getEmbeddedServletContainer(
            ServletContextInitializer... initializers) {
        Tomcat tomcat = new Tomcat();
        File baseDir = (this.baseDirectory != null ? this.baseDirectory
                : createTempDir("tomcat"));
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        Connector connector = new Connector(this.protocol);
        tomcat.getService().addConnector(connector);
        customizeConnector(connector);
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        configureEngine(tomcat.getEngine());
        for (Connector additionalConnector : this.additionalTomcatConnectors) {
            tomcat.getService().addConnector(additionalConnector);
        }
        // 初始化上下文,加載Servlet
        prepareContext(tomcat.getHost(), initializers);
        return getTomcatEmbeddedServletContainer(tomcat);
    }
初始化Servlet
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
    ……
    if (isRegisterDefaultServlet()) {
        addDefaultServlet(context);
    }
    // 初始化JspServlet
    if (shouldRegisterJspServlet()) {
        addJspServlet(context);
        addJasperInitializer(context);
        context.addLifecycleListener(new StoreMergedWebXmlListener());
    }
    ……
}
// 判斷是否加載jspServlet
protected boolean shouldRegisterJspServlet() {
    return this.jspServlet != null && this.jspServlet.getRegistered() && ClassUtils
            .isPresent(this.jspServlet.getClassName(), getClass().getClassLoader());
}

shouldRegisterJspServlet是重點(diǎn)了,這里ClassUtils.isPresent會(huì)去classLoader里面加載jspServlet(org.apache.jasper.servlet.JspServlet),但是classpath里面沒有這個(gè)類。addJspServlet沒有被執(zhí)行

被吃掉的異常

繼續(xù)跟進(jìn)(如果addJspServlet被執(zhí)行)

jspServlet對(duì)象被添加到Tomcat上下文中,并且以jsp擴(kuò)展名為key放到HashMap中,接下來猜想,當(dāng)有web請(qǐng)求會(huì)通過jsp擴(kuò)展名去找到j(luò)spServlet對(duì)象,然后執(zhí)行jsp。

驗(yàn)證

訪問http://localhost:8080/jsp/home,請(qǐng)求首先被tomcat容器攔截到,然后查找適合的servlet來處理(Tomcat本身是Servlet容器,通過servlet來響應(yīng)請(qǐng)求,Spring也是通過注冊(cè)servlet到tomcat才能處理請(qǐng)求的,當(dāng)然Jsp也就是servlet),我們來看下核心類org.apache.catalina.mapper.Mapper

public void map(MessageBytes host, MessageBytes uri, String version,
                MappingData mappingData) throws IOException {

    if (host.isNull()) {
        host.getCharChunk().append(defaultHostName);
    }
    host.toChars();
    uri.toChars();
        // 通過uri,找servlet映射
    internalMap(host.getCharChunk(), uri.getCharChunk(), version,
            mappingData);
}
// 匹配servlet的核心方法
private final void internalMapWrapper(ContextVersion contextVersion,
                                      CharChunk path,
                                      MappingData mappingData) throws IOException {
      // 很多匹配規(guī)則,這我們關(guān)注 Extension Match (擴(kuò)展名)
    // Rule 3 -- Extension Match
    MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;
    if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
        internalMapExtensionWrapper(extensionWrappers, path, mappingData,
                true);
    }
    // Rule 7 -- Default servlet
    if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
        if (contextVersion.defaultWrapper != null) {
              // 默認(rèn)使用org.springframework.web.servlet.DispatcherServlet
            mappingData.wrapper = contextVersion.defaultWrapper.object;
     }}
}

我們的請(qǐng)求path是:/jsp/home,所以沒有匹配Rule 3,而是使用默認(rèn)servlet,那么這個(gè)請(qǐng)求被spring的dispatcherServlet接管,然后執(zhí)行controller

@RequestMapping("/jsp/home")
public String home() {
    return "home";
}

方法執(zhí)行完畢,spring會(huì)去加載home這個(gè)view,由于我們整合了jsp,所以通過配置spring.mvc.view.prefix=/WEB-INF/jsp/ 這個(gè)路徑下,尋找home.jsp文件,然后將請(qǐng)求轉(zhuǎn)發(fā)(這里大家需要了解一下,請(qǐng)求轉(zhuǎn)發(fā)和重定向的區(qū)別)到/WEB-INF/jsp/home.jsp。

處理jsp請(qǐng)求
請(qǐng)求(WEB-INF/jsp/home.jsp)被Tomcat再次攔截,匹配Rule 3,通過擴(kuò)展名jsp,在map中獲取到j(luò)spServlet對(duì)象,給大家截圖

總結(jié)

簡(jiǎn)單總結(jié)一下,本文闡述的問題并不是日常開發(fā)中的主要問題(可能連主要問題都算不上,誰會(huì)用main去調(diào)試??),但是遇到了就花時(shí)間來研究一下,還是有所收獲的。

分析問題思路

Spring Boot 初始化的部分流程

請(qǐng)求轉(zhuǎn)發(fā)和重定向的區(qū)別

另外大家注意如果pom文件中去掉,再正常部署到tomcat容器中,會(huì)有jar沖突,建議大家試驗(yàn)過后,修改回去。

最后

如果覺得我的文章對(duì)您有用,請(qǐng)點(diǎn)贊、收藏。您的支持將鼓勵(lì)我繼續(xù)創(chuàng)作!

為了提高大家學(xué)習(xí)效果,錄制了同步的視頻課程,還望大家支持視頻課程

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70110.html

相關(guān)文章

  • Spring Boot - 整合Jsp/FreeMarker

    摘要:大家自己了解一下的使用方法,我這里就不進(jìn)行詳細(xì)的講述了。啟動(dòng)方式兩種方式都可以主函數(shù)啟動(dòng)或者驗(yàn)證訪問頁面,驗(yàn)證是否輸出了當(dāng)前時(shí)間。為了提高大家學(xué)習(xí)效果,錄制了同步的視頻課程,還望大家支持視頻課程 Spring Boot - 初識(shí) Hello World 索引 Spring Boot - 初識(shí) Hello World Spring Boot - Servlet、過濾器、監(jiān)聽器、攔截器 ...

    AbnerMing 評(píng)論0 收藏0
  • Spring Boot - 單元測(cè)試(Junit4&Mockito)

    摘要:當(dāng)面講給你聽講堂地址,或許是最實(shí)用的教程,新課促銷中,只要你敢來,保你收貨滿滿。優(yōu)惠報(bào)名全程擼碼快速入門教程全原價(jià),優(yōu)惠價(jià)全程擼碼進(jìn)階全原價(jià),優(yōu)惠價(jià) 回顧 Spring Boot - 初識(shí) Hello World Spring Boot - Servlet、過濾器、監(jiān)聽器、攔截器 Spring Boot - 靜態(tài)資源處理、啟動(dòng)加載、日志處理 Spring Boot - 部署Deplo...

    raoyi 評(píng)論0 收藏0
  • Spring Boot - 自定義啟動(dòng)banner

    摘要:背景這段時(shí)間較忙,有些想念小紅,為了表達(dá)我對(duì)小紅的思念之情,決定將啟動(dòng)的研究一下,看看是否能夠自定義,讓我天天能夠看到她。 背景 這段時(shí)間較忙,有些想念小紅,為了表達(dá)我對(duì)小紅的思念之情,決定將spring boot啟動(dòng)的banner研究一下,看看是否能夠自定義,讓我天天能夠看到她。 展示 經(jīng)過調(diào)研,發(fā)現(xiàn)自定義banner是一個(gè)輕松愉快的過程,忍不住讓我多啟動(dòng)幾次,先看看效果:(省略了一...

    CollinPeng 評(píng)論0 收藏0
  • Spring Boot - 表單校驗(yàn)(JSR303&Hibernate Validator)

    摘要:初步使用主要使用注解的方式對(duì)進(jìn)行校驗(yàn),第一個(gè)例子在需要校驗(yàn)的字段上指定約束條件然后在中可以這樣調(diào)用,加上注解即可。如果校驗(yàn)失敗,默認(rèn)會(huì)返回框架的出錯(cuò)信息。指定到的分組名會(huì)全部進(jìn)行校驗(yàn),不指定的不校驗(yàn)。 Spring Boot - 表單校驗(yàn)(JSR303&Hibernate Validator) 回顧 Spring Boot - 初識(shí) Hello World Spring Boot -...

    tinyq 評(píng)論0 收藏0
  • Spring-Boot學(xué)習(xí)筆記

    摘要:學(xué)習(xí)筆記使用很容易創(chuàng)建一個(gè)獨(dú)立運(yùn)行運(yùn)行內(nèi)嵌容器準(zhǔn)生產(chǎn)級(jí)別的基于框架的項(xiàng)目,使用你可以不用或者只需要很少的配置。異常消息如果這個(gè)錯(cuò)誤是由異常引起的。錯(cuò)誤發(fā)生時(shí)請(qǐng)求的路徑。 Spring-Boot 1.5 學(xué)習(xí)筆記 使用Spring Boot很容易創(chuàng)建一個(gè)獨(dú)立運(yùn)行(運(yùn)行jar,內(nèi)嵌Servlet容器)、準(zhǔn)生產(chǎn)級(jí)別的基于Spring框架的項(xiàng)目,使用Spring Boot你可以不用或者只需要很...

    curlyCheng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<