سؤال


We have a situation where we're giving the super-users of our marketing website the ability to directly search for a product with its slug. The link they hit redirects to the actual page for that product. This works fine for english locales. However in case of non-english locales where the slugs have been localised, the redirect causes all accented characters to be replaced by '?'.

For example, http://domain.xx.be/fr/category/catégorie/product_name redirects to http://domain.xx.be/fr/category/cat?gorie/product_name which gives a 404.

Is there a way to retain the accented characters in the redirect url when using the play mvc Results api.
P.S. We get the absolute redirect url as part of a json response from a different API.

EDIT: adding some code for clarity

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

java.net.URI#toASCIIString to the rescue.

From the documentation

Returns the content of this URI as a string.

If this URI was created by invoking one of the constructors in this class then a string equivalent to the original input string, or to the string computed from the originally-given components, as appropriate, is returned. Otherwise this URI was created by normalization, resolution, or relativization, and so a string is constructed from this URI's components according to the rules specified in RFC 2396, section 5.2, step 7.

So your code becomes

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
  }
}

نصائح أخرى

You need to play a little with encodings, in Java it works for me:

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");
}

It encodes the special accented chars to URL entities but brings common URL characters back to live after all

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top