覆盖HttpServletRequest中的getContextPath(用于URL重写)

时间:2008-11-03 22:52:17

标签: java java-ee url-rewriting servlet-filters

我有一个网络应用程序,我想扩展以支持使用新网址的多种语言。例如,www.example.com / home.do保留英语,但www.example.com/es/home.do是西班牙语。我的第一个想法是创建一个过滤器,它将/es/home.do等传入的URL重写为/home.do(并在请求中设置Locale);这很好用。 Filter用一个HttpServletRequestWrapper包装ServletRequest,它覆盖了getContextPath()以返回语言:

class FakeContextRequest extends HttpServletRequestWrapper {

  private String context = "";
  FakeContextRequest(HttpServletRequest request, String context) {
    super(request);
    // snip some validation code
    this.context = request.getContextPath() + context;
  }
  @Override
  public String getContextPath() {
    return this.context;
  }
}

我的过滤器转发到相应的请求,如下所示:

FakeContextRequest fr = new FakeContextRequest(request, lang);
fr.getRequestDispatcher(newResourceName).forward(fr, response);

我的问题是下一个servlet没有正确转发。下一个servlet(通常是Struts ActionServlet)转发到JSP(通常使用Struts Tiles);当我到达JSP时,HttpServletRequest被包装了好几次,并且有问题的对象报告上下文是空的(根上下文,这是实际部署应用程序的地方)。

我希望重写上下文,以便所有已存在的上下文感知代码可以自动将语言插入到写入的URL中。这可能吗?

编辑:我通过使用包装的HttpServletResponse而不是包装的HttpServletRequest解决了我的问题;我在response.encodeURL()方法中重写了URL。

3 个答案:

答案 0 :(得分:1)

我不确定覆盖getContextPath()是否足以解决您的问题。如果Struts正在调用ServletContext.getContextPath()或使用getRequestURI()等等,该怎么办?

答案 1 :(得分:0)

据我所知,执行此操作的传统方法是使用accept-language HTTP标头。表示语言是演示文稿详细信息,不应由用于在应用程序中导航的URL集表示。

答案 2 :(得分:0)

我通过在response.encodeURL()和朋友中进行URL重写来解决我的问题。请求对象在整个请求链中被包装和替换,但响应对象似乎是通过unmolested进行的。这非常可靠。