我们在这里遇到了同样的情况,即我们的产品也需要以地球上可能的每种语言向用户显示有意义的 URL。我们所有的工具和技术都支持 UTF-8,所以这没有问题。转义 UTF-8 字符在技术上是可行的,但 IE (7, 8) 显示难看的转义 URL,而 Firefox 取消转义并显示漂亮的 url,即 '/français/Banane.html' 将在 IE 中显示为 '/fran% C3%A7ais/Banane.html'。POST 后的 GET / 表单提交后的重定向根本不起作用,既不发送 UTF-8 url,也不转义 UTF-8 url。我们还尝试使用 XML 样式的数字实体编码,但没有成功。
然而,我们终于找到了一种在 POST 之后成功重定向的方法:使用 ISO-8859-1 对 UTF-8 字符串进行字节编码。无论如何,我们都没有真正理解它是如何工作的(浏览器如何知道如何解码,因为每个 utf-8 字符的字节数可能会有所不同,浏览器如何知道它最初是 utf-8?),但是确实如此。
这是一个简单的 servlet 来尝试:
package springapp.web.servlet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = -1743198460341004958L;
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String url = "çöffte.html";
try {
ServletContext context = req.getSession().getServletContext();
// read utf8 encoded russian url
if (context.getResource("/WEB-INF/ru_url.txt") != null){
InputStream is = context.getResourceAsStream("/WEB-INF/ru_url.txt");
if (is != null){
url = IOUtils.toString(is, "UTF-8");
System.out.println(String.format("Redirecting to [%s]", url));
}
}
}
catch (FileNotFoundException fNFEx) {
fNFEx.printStackTrace();
}
catch (IOException ioEx) {
ioEx.printStackTrace();
}
byte[] utfBytes = url.getBytes("UTF-8");
String result = new String(utfBytes, "ISO-8859-1");
resp.sendRedirect(result);
// does not work:
//resp.sendRedirect(url);
//resp.sendRedirect(Utf8UrlEscaper.escapeUtf8(url));
//resp.sendRedirect(Utf8UrlEscaper.escapeToNumericEntity(url));
}
}
对于重定向目标,复制并粘贴任何本地语言 url,例如来自 wikipedia 的 utf-8 编码(没有 BOM!)文件,并将其保存在 WEB-INF 目录中。在我们的示例中,我们采用了一个俄语 url ( http://ru.wikipedia.org/wiki/Заглавная_страница ) 并将其保存在一个名为 'ru_url.txt' 的文件中。
我们创建了一个简单的 SpringMVC 应用程序,将任何 *.abc url 映射到测试 servlet。现在,如果您启动应用程序并输入“localhost:8080/springmvctest/a.abc”之类的内容,您应该被重定向到俄罗斯维基百科站点,并且浏览器(IE 和 Firefox、Safari 或其他可能不会)应该显示一个不错的 utf- 8 位编码的原生俄罗斯网址。