【问题标题】:Override getContextPath in an HttpServletRequest (for URL rewriting)在 HttpServletRequest 中覆盖 getContextPath(用于 URL 重写)
【发布时间】:2010-09-20 14:08:13
【问题描述】:

我有一个网络应用程序,我想扩展它以支持具有新 URL 的多种语言。例如,www.example.com/home.do 保持英语,但 www.example.com/es/home.do 是西班牙语。我的第一个想法是创建一个过滤器,它将 /es/home.do 之类的传入 url 重写为 /home.do (并在请求中设置区域设置);这很好用。 Filter 使用 HttpServletRequestWrapper 包装 ServletRequest,该 HttpServletRequestWrapper 覆盖 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。

【问题讨论】:

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


    【解决方案1】:

    据我所知,执行此操作的常规方法是使用接受语言 HTTP 标头。表示语言是一种表示细节,不应由一组 URL 来表示以在应用程序中导航。

    【讨论】:

    • accept-language 标头不起作用,因为它与搜索引擎不兼容。搜索引擎需要唯一的链接才能抓取不同语言的内容。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      猜你喜欢
      • 2016-02-16
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      • 2014-01-13
      相关资源
      最近更新 更多