Java 重写HttpServletRequest中的getContextPath(用于URL重写)

Java 重写HttpServletRequest中的getContextPath(用于URL重写),java,jakarta-ee,url-rewriting,servlet-filters,Java,Jakarta Ee,Url Rewriting,Servlet Filters,我有一个web应用程序,我想通过新的URL扩展以支持多种语言。例如,www.example.com/home.do使用英语,但www.example.com/es/home.do使用西班牙语。我的第一个想法是创建一个过滤器,将传入的URL重写为/es/home.do到/home.do(并在请求中设置区域设置);这个很好用。筛选器使用HttpServletRequestWrapper包装ServletRequest,该包装覆盖getContextPath()以返回语言: class FakeCon

我有一个web应用程序,我想通过新的URL扩展以支持多种语言。例如,www.example.com/home.do使用英语,但www.example.com/es/home.do使用西班牙语。我的第一个想法是创建一个过滤器,将传入的URL重写为/es/home.do到/home.do(并在请求中设置区域设置);这个很好用。筛选器使用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。

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

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

我通过在响应.encodeURL()和friends中重写URL解决了我的问题。请求对象在整个请求链中被包装和替换,但响应对象似乎没有受到干扰。这工作非常可靠。

accept language标头无法工作,因为它与搜索引擎不兼容。搜索引擎需要独特的链接,以便对不同语言的内容进行爬行。我认为这是URLRewiterFilter项目中使用的方法