簡體   English   中英

為什么WEB-INF文件夾里面的jsp文件有效,但放在WEB-INF下的文件夾下不行?

[英]Why jsp files inside WEB-INF folder works , but placed under a folder under WEB-INF doesn't?

當我的jsp文件在WEB-INF文件夾中(作為/WEB-INF/file.jsp)時,我可以從localhost:8080 / ProjectCtxtRoot /訪問它們,但如果將它們放在/ WEB-中我無法訪問它們INF / JSP / file.jsp?

我在web.xml中更改了welcome-list標記中的路徑,如下所示

<welcome-file-list>
       <welcome-file>/JSP/fileName.jsp</welcome-file>
</welcome-file-list>

我還更改了dispatcher-servlet.xml,如下所示

   <bean id="jspViewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" /> 

它仍然無效。 用於上述案例的網址是

 localhost:8080/ContextRoot/jsp/
 localhost:8080/ContextRoot/jsp/fileName.jsp
 localhost:8080/ContextRoot/jsp/fileName 

它不適用於上述任何網址。

但它正在工作的時候

 <welcome-file-list>
       <welcome-file>/fileName.jsp</welcome-file>
</welcome-file-list>

dispatcher-servlet.xml如下

<bean id="jspViewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/"
      p:suffix=".jsp" /> 

用於上述案例的URL是localhost:8080 / ContextRoot /並且它可以工作。

我使用tomcat v 7.0服務器。 我在Eclipse IDE中刷新我的項目,然后清理它,構建它,使用mvn clean install構建war,然后從tomcat manager主頁選擇war並進行部署。 我每次都這樣做。

這就是diapatcher-servlet.xml在整個過程中的外觀。 我只是改變上面所說的特定部分

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd     
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <mvc:annotation-driven/>

    <context:component-scan base-package="com.projectName.www" />

    <!-- Factory bean that creates the Mongo instance -->
    <bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
        <property name="host" value="localhost" />
    </bean>

    <!-- MongoTemplate for connecting and quering the documents in the database -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongo" ref="mongo" />
        <constructor-arg name="databaseName" value="tableName" />
    </bean>

    <!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />



    <bean id="jspViewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" /> 

  <!--   <bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver"/>

    <bean class=
    "org.springframework.web.servlet.view.tiles2.TilesConfigurer"> -->
 <!--  <property name="definitions">
    <list>
      <value>/WEB-INF/views/views.xml</value>
    </list>
  </property> 
</bean> -->




</beans>

這就是我的web.xml的樣子

<web-app>

<!--   <display-name>Archetype Created Web Application</display-name> -->

   <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/src/main/webapp/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </context-param> 

   <!--  <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> -->

    <welcome-file-list>
       <welcome-file>/fileName.jsp</welcome-file>
    </welcome-file-list> 


</web-app>

好。 當我將整個jsp文件夾從/webapp/WEB-INF/jsp/fileName.jsp移動到/webapp/jsp/fileName.jsp時,它可以工作。 我想知道1.為什么現在有效? 這是正確的做事方式嗎? 3.當url為localhost:8080 / CtxtRoot / jsp /或localhost:8080 / CtxtRoot / jsp / search.jsp時,它可以工作,但它不適用於localhost:8080 / AnnaUnivResults / jsp / search。 為什么會這樣?

我認為這里有幾個問題:

  1. 你對Spring MVC的路徑感到困惑
  2. 您沒有正確配置您的Web xml

不幸的是我無法為你詳細介紹每一個細節,很多彈簧都是可配置的,所以我的解釋只是涵蓋了最基本的場景。 如果有人發現錯誤,請告訴我,我會解決它。

對於路徑,可能有助於逐步思考問題。

  1. 您從瀏覽器請求URL,瀏覽器查看協議,主機和端口,並使用DNS查找要連接的相應IP地址。
  2. 您的瀏覽器和主機之間建立了連接。 主機查找在您指定的端口上運行的進程,如果任何安全系統允許TCP連接,請求將流式傳輸到在該端口(Web服務器)上運行的進程。
  3. Web服務器根據端口之后的內容做出決策,具體來說,它通過查看給定的路徑來確定Web應用程序上下文的內容。 一旦確定了應用程序上下文根,它就知道哪個Web應用程序應該處理該請求。 該決定基於您配置Web服務器的方式,您可以讓Web應用程序處理沒有​​上下文根的請求或特定的上下文根。 例如,如果您請求localhost:8080/CtxtRoot/jsp/ ,您可以在服務器上有一個Web應用程序,其上下文根為“CtxtRoot”,它將處理該請求。 或者,您可以擁有一個具有“”上下文的應用程序,它可以處理該請求。 這取決於您配置服務器的方式,默認情況下Tomcat將使用war名稱作為上下文根。
  4. Web應用程序接收請求。 雖然它知道所請求的完整URL,但它只根據上下文根之后的所有內容做出決策。 因此,例如,對localhost:8080/CtxtRoot/jsp/的請求,Web應用程序將基於'jsp'作為路徑路由事物。
  5. Web應用程序有一個過濾器鏈,它首先提交請求。 如果過濾器的模式與請求匹配,則該過濾器可以評估請求。 它可能會阻止請求,處理請求或傳遞請求。 我不會說太多,因為你的問題不涉及過濾器。
  6. Web應用程序查找其模式與請求匹配的資源,它首先考慮servlet,然后是靜態資源。 在上下文之后出現的url部分是它嘗試匹配的部分,因此如果請求是針對localhost:8080/CtxtRoot/jsp/ ,並且上下文根是'CtxtRoot',那么Web應用程序正在比較'/ jsp /'到所有servlet映射。 對WEB-INF中的靜態資源的請求將始終被拒絕,但servlet和過濾器可以並且確實從WEB-INF返回數據。
  7. 我將繼續假設請求被發送到Spring DispatcherServlet,它接收請求,並考慮servlet路徑之后的所有內容。 Spring的DispatcherServlet查找一個Controller,其路徑與servlet路徑之后的路徑匹配。 servlet路徑基本上就是你在web xml中的servlet映射中放置的內容。 讓我舉一個例子,假設您有一個Web應用程序,其上下文為“app”,它有一個Spring MVC servlet,其servlet映射為'/ mvc',以及一個處理路徑'sales'的控制器,那么你可以使用http://localhost:8080/app/mvc/sales訪問該控制器。
  8. 如果DispatcherServlet找不到Controller,我認為它將傳入的請求視為由控制器返回,因此如果子路徑是'sales',那么它會將其作為參數傳遞給視圖解析器。 如果找不到,則服務器返回未找到的錯誤。
  9. 通常,Controller在完成后返回一個字符串,這是資源的路徑。 它可以將“流行”作為字符串返回。 Spring然后將它轉發給ViewResolver,我假設你正在使用InternalResourceViewResolver。 它將查看前綴和后綴,並基本上將它們包含在給定的內容中。 因此,如果前綴是'/ WEB-INF / views /',后綴是'.jsp',參數是'熱門',那么它將在'/WEB-INF/views/popular.jsp中查找資源”。 它實際上只是將這些字符串連接起來構成一條路徑。 該路徑始終相對於Web應用程序根目錄。 如果生成的路徑是jsp文件,則在返回之前將對其進行解釋。
  10. 然后它最終返回給用戶。

從您的示例中,您正在請求localhost:8080 / ContextRoot / jsp / fileName,因此看起來'CtxRoot'是上下文根,您的servlet的路徑是'/',因此它應該將之后的任何內容傳遞給控制器​​。 當DispatcherServlet收到請求時,它正在搜索將'jsp'作為路徑處理的控制器。 由於你沒有,它決定將其視為資源路徑。 它使用視圖解析器並形成路徑/WEB-INF/jsp/jsp/fileName.jsp,這顯然不存在。

假設您已經請求localhost:8080 / ContextRoot / fileName,請求將到達DispatcherServlet,它將找不到將“fileName”作為路徑處理的Controller,因此會將其視為資源。 它將形成路徑/WEB-INF/jsp/fileName.jsp,這將返回結果。

但是,您的Web xml未配置為初始化spring。 因此,您的Web應用程序實際上正在處理您的每個請求,就好像它們是針對Web應用程序根目錄的資源一樣。 我相信,如果你已經正確地初始化了Spring的請求,它可能會有效。

以下是如何執行此操作的一個很好的示例:

http://www.mkyong.com/spring3/spring-3-mvc-hello-world-example/

請注意,他的web xml有一個ContextLoaderListener,它在你的注釋中被注釋掉,這對於在web應用程序中初始化spring非常重要。 我還在調度程序中看到了路徑/ src / main / resources的注釋,但是web xml中的所有路徑都應該相對於Web應用程序根目錄。 在運行時,Web服務器不了解您的項目,並且'src'不是Web應用程序根目錄中的目錄。 另請注意,您的MVC內容可能與主彈簧上下文不同,這很常見。

我想如果你做這些事情它會起作用:

  1. 將您的jsp移動到/WEB-INF/jsp/fileName.jsp
  2. 更新您的應用程序上下文,因此'/ WEB-INF / jsp /'是前綴,'。jsp'是后綴。
  3. 將上下文加載器偵聽器添加到Web xml,並設置相對於應用程序上下文根的contextConfigLocation路徑。 例如,它可能是/WEB-INF/appContext.xml
  4. 提出要求

    本地主機:8080 / CtxtRoot /文件名

此外,您一直在談論歡迎文件,但您提供了完整的資源路徑。 歡迎文件僅在用戶向目錄的根目錄發出請求時才會起作用,如下所示:

localhost:8080/CtxtRoot/

該請求將被轉發到歡迎文件。 我認為你唯一一次嘗試過,jsp碰巧在你的應用程序根目錄中,並被配置為歡迎文件,所以它有效。 雖然它“有效”,但實際上並沒有使用spring來返回它。

祝你好運。

WEB-INF之外的所有內容都是公開可用的,不對其應用任何身份驗證(我們可以通過在web.xml中定義scurity約束來應用),但WEB-INF內的所有資源都是安全的。 您可以將靜態頁面保留在WEB-INF之外,以及動態頁面,例如WEB-INF中的配置文件,帳戶。 請交叉檢查我可能是錯的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM