在Spring框架中如何对URL进行编码?

5

大家好, 我有一个控制器中的POST方法,可以重定向到一个新页面。实现方式如下:

@RequestMapping(method = RequestMethod.POST)
    public String post(HttpServletRequest request) {

        return "redirect:http://www.x.appName.com/myPage";

    }

假设用户在重定向之前已经有一个会话,并且我想在重定向之前对新的URL进行编码以维护用户会话,应该如何做?
3个回答

7
您可以将HttpServletResponse作为参数传递,并使用encodeRedirectURL(..)方法:
String url = "http://www.x.appName.com/myPage";
url = response.encodeRedirectURL(url);
return "redirect:" + url;

但首先请确保Spring没有自动为您完成此操作。

谢谢,但我不确定Spring是否会自动完成这个操作,有精通Spring的人可以告诉我们吗? - Mahmoud Saleh
“试试看”是一种非常糟糕的方法。它可能在他使用的版本/设置中以某种方式工作,但在另一个环境中(比如生产环境)可能会有不同的结果。 - David Balažic
自从这个答案发布以来已经过了很长时间,现在你是否有关于Spring(Security)是否会自动执行此操作的任何信息? - Amit
我不知道 :) 如果你调查并有答案,请告诉我们。 - Bozho

1
UriComponentsBuilder的build方法默认为“false”,这将触发编码:
UriComponentsBuilder.fromHttpUrl(url).build().toString()

依赖默认值是有风险的,最好/更安全的方式是显式编码。不能保证默认值在未来的某个版本中不会改变。 - Madbreaks

0

Spring doc是解决这类问题的终极资源。此外,您可以从github下载正确版本的代码,并进行调试以获得答案。至于本题,请查看这里http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/mvc.html#mvc-redirecting-redirect-prefix或者查看下方RedirectView类的源代码(适用于spring 4.1.0):

    protected void appendQueryProperties(StringBuilder targetUrl, Map<String, Object> model, String encodingScheme)
        throws UnsupportedEncodingException {

    // Extract anchor fragment, if any.
    String fragment = null;
    int anchorIndex = targetUrl.indexOf("#");
    if (anchorIndex > -1) {
        fragment = targetUrl.substring(anchorIndex);
        targetUrl.delete(anchorIndex, targetUrl.length());
    }

    // If there aren't already some parameters, we need a "?".
    boolean first = (targetUrl.toString().indexOf('?') < 0);
    for (Map.Entry<String, Object> entry : queryProperties(model).entrySet()) {
        Object rawValue = entry.getValue();
        Iterator<Object> valueIter;
        if (rawValue != null && rawValue.getClass().isArray()) {
            valueIter = Arrays.asList(ObjectUtils.toObjectArray(rawValue)).iterator();
        }
        else if (rawValue instanceof Collection) {
            valueIter = ((Collection<Object>) rawValue).iterator();
        }
        else {
            valueIter = Collections.singleton(rawValue).iterator();
        }
        while (valueIter.hasNext()) {
            Object value = valueIter.next();
            if (first) {
                targetUrl.append('?');
                first = false;
            }
            else {
                targetUrl.append('&');
            }
            String encodedKey = urlEncode(entry.getKey(), encodingScheme);
            String encodedValue = (value != null ? urlEncode(value.toString(), encodingScheme) : "");
            targetUrl.append(encodedKey).append('=').append(encodedValue);
        }
    }

    // Append anchor fragment, if any, to end of URL.
    if (fragment != null) {
        targetUrl.append(fragment);
    }
}

简而言之,如果您知道在哪里放置值,Spring将替您完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接