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

时间:2014-09-18 04:43:56

标签: java spring jsp spring-mvc web

当我的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" /> 

用于上述情况的网址是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。为什么会这样?

2 个答案:

答案 0 :(得分:23)

我认为这里有几个问题:

  1. 你对使用spring MVC
  2. 的路径感到困惑
  3. 您没有正确配置您的web xml
  4. 不幸的是,我无法覆盖你的每一个细节,很多弹簧都是可配置的,所以我的解释只是涵盖最基本的场景。如果有人发现错误,请告诉我,我会解决它。

    对于路径,可能有助于逐步思考问题。

    1. 您从浏览器请求URL,浏览器查看协议,主机和端口,并使用DNS查找要连接的相应IP地址。
    2. 您的浏览器和主机之间建立了连接。主机查找在您指定的端口上运行的进程,如果任何安全系统允许TCP连接,则请求将流式传输到在该端口(Web服务器)上运行的进程。
    3. Web服务器根据端口之后的内容做出决策,具体来说,它通过查看给定的路径来确定Web应用程序上下文的内容。一旦确定了应用程序上下文根,它就知道哪个Web应用程序应该处理该请求。该决定基于您配置Web服务器的方式,您可以让Web应用程序处理没有​​上下文根的请求或特定的上下文根。例如,如果您请求localhost:8080/CtxtRoot/jsp/,则可以在服务器上安装一个Web应用程序,其上下文根为&#34; CtxtRoot&#34;,它将处理该请求。或者,您可以拥有一个具有&#34;&#34;对于上下文,它可以处理该请求。这取决于您如何配置服务器,默认情况下,Tomcat将使用war name作为上下文根。
    4. Web应用程序收到请求。虽然它知道所请求的完整URL,但它只根据上下文根之后的所有内容做出决策。例如,根据对localhost:8080/CtxtRoot/jsp/的请求,Web应用程序将基于&#39; jsp&#39;来路由事物。作为路径。
    5. Web应用程序有一个过滤器链,它首先提交请求。如果过滤器的模式与请求匹配,则该过滤器可以评估该请求。它可能会阻止请求,处理请求或传递请求。我不会说更多,因为你的问题不涉及过滤器。
    6. Web应用程序查找其模式与请求匹配的资源,它首先考虑servlet,然后是静态资源。在上下文之后出现的url部分是它尝试匹配的部分,因此如果请求是localhost:8080/CtxtRoot/jsp/,并且上下文根是&#39; CtxtRoot&#39;,则Web应用程序正在比较&#39; ; / JSP /&#39;到所有servlet映射。对WEB-INF中的静态资源的请求将始终被拒绝,但servlet和过滤器可以并且确实从WEB-INF返回数据。
    7. 我将继续假设请求已发送到Spring DispatcherServlet,它接收请求,并考虑servlet路径之后的所有内容。 Spring的DispatcherServlet查找一个Controller,其路径与servlet路径之后的路径匹配。 servlet路径基本上就是你在web xml中的servlet映射中放置的内容。让我举一个例子,假设您有一个Web应用程序,其上下文是“应用程序”,它有一个Spring MVC servlet,其servlet映射为&#39; / mvc&#39;,以及一个处理路径&#39; sales&#39;的控制器,然后你可以通过http://localhost:8080/app/mvc/sales到达该控制器。
    8. 如果DispatcherServlet找不到控制器,我相信它会将传入的请求看作是控制器返回的,所以如果子路径是&#39; sales&#39;,那么它会将其作为视图解析器的参数。如果找不到,则服务器返回未找到的错误。
    9. 通常,Controller在完成后返回一个字符串,这是资源的路径。它可以回归流行的#39;作为一个字符串。 Spring然后将它转发给ViewResolver,我假设您正在使用InternalResourceViewResolver。它将查看前缀和后缀,并基本上将它们包含在给定的内容中。因此,如果前缀是&#39; / WEB-INF / views /&#39;,则后缀是&#39; .jsp&#39;,并且参数是“#39”,那么它将会在&#39; /WEB-INF/views/popular.jsp'寻找资源。它实际上只是将这些字符串连接起来构成一条路径。该路径始终相对于Web应用程序根目录。如果生成的路径是jsp文件,则在返回之前将对其进行解释。
    10. 然后它最终返回给用户。
    11. 从您的示例中,您正在请求localhost:8080 / ContextRoot / jsp / fileName,因此它看起来像是&#39; CtxRoot&#39;是上下文根,您的servlet的路径是&#39; /&#39;,所以它应该将之后的内容传递给控制器​​。当DispatcherServlet收到请求时,它正在搜索处理&#39; jsp&#39;作为一条道路。由于你没有,它决定将其视为资源路径。它使用视图解析器并形成路径/WEB-INF/jsp/jsp/fileName.jsp,这显然不存在。

      假设您已经请求localhost:8080 / ContextRoot / fileName,请求将到达DispatcherServlet,它将找不到处理&#39; fileName&#39;作为一条路径,因此将其视为一种资源。它将形成路径/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服务器不了解您的项目,并且&#39; src&#39;不是您网络应用程序根目录中的目录。另请注意,您的MVC内容可能与主弹簧上下文不同,这很常见。

      我认为如果你做这些事情就行了:

      1. 将您的jsp移动到/WEB-INF/jsp/fileName.jsp
      2. 更新您的应用内容,以便&#39; / WEB-INF / jsp /&#39;是前缀,&#39; .jsp&#39;是后缀。
      3. 将上下文加载器侦听器添加到Web xml,并设置相对于应用程序上下文根的contextConfigLocation路径。例如,它可能是/WEB-INF/appContext.xml
      4. 发出请求

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

      5. 此外,您一直在讨论欢迎文件,但您提供了完整的资源路径。欢迎文件仅在用户向目录的根目录发出请求时才会起作用,如下所示:

        localhost:8080/CtxtRoot/
        

        该请求将被转发到welcome-file。我认为你唯一一次尝试过,jsp碰巧在你应用程序的根目录中,并被配置为欢迎文件,所以它有效。虽然它已经工作了#34;但实际上并没有使用spring来返回它。

        祝你好运。

答案 1 :(得分:-3)

WEB-INF之外的所有内容都是公开可用的,不会对其进行身份验证(我们可以通过在web.xml中定义scurity约束来应用),但WEB-INF中的所有资源都是安全的。您可以将静态页面保留在WEB-INF之外,以及动态页面,例如WEB-INF中的配置文件,帐户。 请交叉检查我可能是错的。