【问题标题】:Spring:url not resolving links correctlySpring:url 无法正确解析链接
【发布时间】:2012-03-08 14:55:32
【问题描述】:

我对 Spring 框架和 Web 应用程序很陌生,尽管我对 Java 有一定的经验。当我在本地 tomcat 服务器上运行我的网站时,URL 是:http://localhost:8080/myApp/

现在请求映射将我委托到我的主页:

@RequestMapping(value = "/", method = RequestMethod.GET)
public String someMethod(Model model) { ... 
   return "index"; }

现在在文件index.xhtml 中,我使用<a href="apps/">link</a> 链接到另一个页面 但是当我想链接回索引页面时,我必须使用<a href="../index/">link</a>。我搜索了一个解决方案,发现:

<spring:url value='/apps' var="apps_url" />
<a href="${apps_url}">link</a>

但 spring:url 总是解析为 http://localhost:8080/myApp/ - 我当前所在的页面。此外,当我只使用这样的链接:&lt;a href="/otherSite"&gt;link&lt;/a&gt; 时,它总是解析为 http://localhost:8080/otherSite 而不是 http://localhost:8080/myApp/otherSite,就像我预期的那样。我怎样才能让我的链接工作? http://localhost:8080/myApp 是隐式定义为我的上下文还是可以/应该将其更改为 http://localhost:8080/

另外,本地 tomcat 服务器上的 URL 和 Web 应用程序发布时的 URL 之间是否有任何联系?

这是我的一些应用程序文件:

servlet-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <context:component-scan base-package="myApp" />

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- Handles HTTP GET requests for /resources/** and /css/** by efficiently 
    serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />
    <resources mapping="/css/**" location="/css/" />

    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".xhtml" />
    </beans:bean>

</beans:beans>

摘自 web.xml:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

【问题讨论】:

    标签: java spring jakarta-ee spring-mvc


    【解决方案1】:

    最好将所有链接按如下方式放置

    <a href="${pageContext.servletContext.contextPath}/othersite"> Other site </a>
    

    ${pageContext.servletContext.contextPath} 总是给你的应用程序根,当你开发时使用http://localhost:8080/myApp,那么你的应用程序根是/myapp,但是当你您希望将您的应用程序置于生产环境中,通常您的应用程序根目录将是 /,在链接之前使用 ${pageContext.servletContext.contextPath} 确保它在这两种情况下都能正常工作

    【讨论】:

    • @ams 和 Jhonathan ,我认为问题是因为我在 Eclipse 之外运行 Tomcat 服务器。 ${pageContext.servletContext.contextPath} 为我解析为“”(空字符串)。我根本找不到任何战争文件。我可以使用 maven 构建我的 spring 应用程序来创建一个 .war 文件,但是在 eclipse 中使用 tomcat 时有什么解决方案可以解决我的问题吗?似乎 Tomcat(隐含地?)使用 localhost:8080/packageName 作为 root 但是当您询问上下文时,它不会返回“packageName”
    • 我在“C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\packageName”中找到了我的项目 - 所以我想按下“保存”在 Eclipse 中,更改被复制到那里并由 tomcat 加载。但是我怎样才能让我的项目检索正确的基本 url?
    • 我无法确切说明为什么它对我不起作用,但使用 ${facesContext.externalContext.requestContextPath} 会返回正确的路径。因此,在这篇文章中接收上下文路径在某种程度上是正确的解决方案。谢谢
    • 以及如何使用 ServletContext 在控制器中获取 ${pageContext.servletContext.contextPath} ?
    【解决方案2】:

    当遇到同样的问题时,我使用 c 库:

     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
     <a href="<c:url value="/otherSite"/>"> Other site </a> 
    

    【讨论】:

      【解决方案3】:

      这应该可以解决问题:

      <spring:url value="/some_link" context="myApp" var="apps_url" />
      <a href="${apps_url}">link</a>
      

      apps_url 应该等于:http://localhost:8080/myApp/some_link

      【讨论】:

      • 这对我不起作用,在页面 http://localhost:8080/myApp/apps 上,网址已解析为 http://localhost:8080/myApp/apps。可能有错误,您当前所在的页面是失败时的默认输出?
      【解决方案4】:

      Tomcat 可以同时执行多个 Web 应用程序。考虑场景:

      • tomcat 在 8080 上运行
      • tomcat web apps 文件夹中运行着三个应用程序
        • appA.war
        • appB.war
        • ROOT.war

      URL http://localhost:8080/ 将获取到 tomcat 的请求,并且 tomcat 必须决定三个应用程序中的哪一个应该为请求提供服务,因为 URL 不识别应用程序,请求将由 tomcat 路由到 ROOT.war,这是Tomcat 中的根网络应用程序。

      当您在 appA.war 中有一个带有 &lt;a href="/otherSite"&gt;link&lt;/a&gt; 的 JSP 时,解析输出的 Web 浏览器将认为该请求应该提交到服务器的根目录,因为 href 以 / 开头,因此浏览器将 togethec当请求到达 tomcat tomcat 时,url http://localhost:8080/otherSite 假定 /otherSite 指的是一个名为 otherSite.war 的网络应用程序,但当然不存在。

      如果您使用&lt;a href="otherSite"&gt;link&lt;/a&gt;,浏览器将假定这是一个相对URL,因此它将请求发送到http://localhost:8080/appA/otherSite,因为生成该URL的页面是在上下文http://localhost:8080/appA之外提供的

      所以一般来说,您需要确保来自 JSP 页面的 URL 是相对的,或者您将上下文名称添加到生成的 url,这就是 &lt;spring:url /&gt;&lt;c:url /&gt; 标签所做的。

      本地 tomcat 服务器上的 url 和 Web应用程序发布时的url?

      上下文的 URL 与 tomcat webapps 文件夹中的 war 文件的名称相同,除非您在 server.xml 或 context.xml 文件中更改它。

      【讨论】:

      • 感谢您的详细解释,但是当我尝试使用 &lt;spring:url value="myApp/otherSite" ... &gt;&lt;spring:url value="/otherSite" context="myApp"&gt; 时,URL 仍然被解析为我当前所在的页面
      • 尝试类似 ">注销 它对我有用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-10
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多