如何在执行301重定向时保留重音字符

时间:2013-11-04 13:54:25

标签: scala playframework-2.0 url-redirection


我们的情况是,我们的营销网站的超级用户能够直接搜索带有slug的产品。他们点击的链接会重定向到该产品的实际页面。这适用于英语语言环境。但是,如果非英语语言环境中slus已被本地化,则重定向会导致所有重音字符被“?”替换。

例如, http://domain.xx.be/fr/category /catégorie/ product_name 重定向到 http://domain.xx.be/fr/category/cat?gorie/product_name ,这会产生404.

使用play mvc Results api时,有没有办法在重定向url中保留重音字符。
我们将绝对重定向url作为来自不同API的json响应的一部分。

编辑:为清晰起见添加一些代码

def getProductPage(slug: String, locale: String) = AsyncAction {
  flow {
    val response = gateway.getPathBySlug(slug, locale).!
    val url = (response.json \ "url").as[String]
    MovedPermanently(url)
  } recover {
    case ex => throw ex
  }
}

2 个答案:

答案 0 :(得分:1)

你需要玩一些编码,在Java中它对我有用:

public static Result bad() {
    return temporaryRedirect("http://fr.wikipedia.org/wiki/Catégorie");
}

public static Result good() {
    return temporaryRedirect(encodeUrl("http://fr.wikipedia.org/wiki/Catégorie"));
}

public static String encodeUrl(String url) {
    try {
        url = URLEncoder.encode(url.trim(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return url
            .replace("%20", "_")
            .replace("%21", "!")
            .replace("%22", "'") // single quotas
            .replace("%24", "$")
            .replace("%27", "'")
            .replace("%28", "(")
            .replace("%29", ")")
            .replace("%2C", ",")
            .replace("%2F", "/")
            .replace("%3A", ":")
            .replace("%3F", "_") // question sign
            .replace("%E2%80%9E", "'") // lower quotas
            .replace("%E2%80%9D", "'") // upper quotas
            .replace("+", "_")
            .replace("%25", "percent");
}

它对URL实体的特殊重音字符进行编码,但将常见的URL字符重新带回来

答案 1 :(得分:0)

java.net.URI#toASCIIString救援。

来自documentation

  

以字符串形式返回此URI的内容。

     

如果此URI是通过调用此中的一个构造函数创建的   class然后是一个等价于原始输入字符串的字符串,或者是   从适当的原始给定组件计算的字符串,   退回。否则,此URI是通过规范化创建的,   解析或相对化,所以从中构造一个字符串   此URI的组件根据RFC 2396中指定的规则,   第5.2节,第7步。

所以你的代码变成了

def getProductPage(slug: String, locale: String) = AsyncAction {
  flow {
    val response = gateway.getPathBySlug(slug, locale).!
    val url = (response.json \ "url").as[String]
    val encodedDestination = new URI(url).toASCIIString
    MovedPermanently(encodedDestination)
  } recover {
    case ex => throw ex
  }
}