如何使用<spring:url>解析相对URI

时间:2016-09-08 09:38:05

标签: spring jsp spring-mvc

我有一个网站索引..... http://localhost/myContext/
REST索引.................. http://localhost/myContext/restController/
和许多REST页面...... http://localhost/myContext/restController/*/*

REST控制器使用相对路径,根据URL动态加载内容。

当直接浏览器访问这些页面时,所有页面都可以正常工作,您可以自由导航。

现在我想使用AJAX将restController/*/*页面直接集成到/myContext/索引中。内容被加载到DIV中; 浏览器的网址永远不会改变

我的浏览器点击网站索引/myContext/
然后AJAX加载/restController/,它指向JSP ...

在JSP内部:<spring:url value="something">直接返回something而不是基于控制器的servletPath /myContext/restController/something

的整个绝对路径

由于<spring:url>返回相对路径,浏览器会尝试点击/myContext/something - 404

我以前使用<form:form>为表单执行此操作,效果很好。该操作是相对于控制器的servletPath创建的。

从相对URI获取<spring:url>(或其他)绝对路径的最简洁方法是什么?

我尝试使用${pageContext.request.requestURI},但它包含JSP文件名(/myContext/restController/something/ctrl.jsp),过滤文件名不会起作用,因为我依赖最后一个短划线的存在与否。< / p>

我还尝试包含<form:form />并使用Javascript恢复操作。它非常丑陋,但它有效......不是一个好的解决方案。

来自<spring:url>的代码:

private String createUrl() throws JspException {
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
        StringBuilder url = new StringBuilder();
        if (this.type == UrlType.CONTEXT_RELATIVE) {
            // add application context to url
            if (this.context == null) {
                url.append(request.getContextPath());
            }
            else {
                if (this.context.endsWith("/")) {
                    url.append(this.context.substring(0, this.context.length() - 1));
                }
                else {
                    url.append(this.context);
                }
            }
        }
        if (this.type != UrlType.RELATIVE && this.type != UrlType.ABSOLUTE && !this.value.startsWith("/")) {
            url.append("/");
        }
        url.append(replaceUriTemplateParams(this.value, this.params, this.templateParams));
        url.append(createQueryString(this.params, this.templateParams, (url.indexOf("?") == -1)));

        String urlStr = url.toString();
        if (this.type != UrlType.ABSOLUTE) {
            // Add the session identifier if needed
            // (Do not embed the session identifier in a remote link!)
            urlStr = response.encodeURL(urlStr);
        }

        // HTML and/or JavaScript escape, if demanded.
        urlStr = htmlEscape(urlStr);
        urlStr = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(urlStr) : urlStr;

        return urlStr;
    }

1 个答案:

答案 0 :(得分:0)

似乎<spring:url>无法正确处理嵌入式JSP文件的相对路径 我必须创建自己的标签来进行此转换。

TAG代码为:

<%@tag trimDirectiveWhitespaces="true" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@attribute name="value"%>
<%@attribute name="var"%>
<%@attribute name="id"%>

<%
    // Fetch the original request_uri from the request and extract its absolute path
    String url_absolute;
    String requestUri = (String) request.getAttribute("javax.servlet.forward.request_uri");
    if (requestUri == null)
        requestUri = (String) request.getRequestURI();

    int lastSlash = requestUri.lastIndexOf('/');
    if (lastSlash >= 0)
        url_absolute = requestUri.substring(0, lastSlash + 1);
    else
        url_absolute = "/"; // Should never happen

    // If a value is defined in the TAG, we add it to the path
    if (value != null)
        url_absolute += value;

    getJspContext().setAttribute("url_absolute", url_absolute);

    // If a var is defined in the TAG, we set its attribute in the request
    if (var != null)
        request.setAttribute(var, url_absolute);
%>

<c:if test="${not empty id}">
    <input type="hidden" id="${id}" value="${url_absolute}">
</c:if>

<c:if test="${empty var and empty id}">
    ${url_absolute}
</c:if>

可以改进此代码以处理范围,上下文和转义属性。