Переопределить getContextPath в HttpServletRequest (для перезаписи URL)

У меня есть веб-приложение, которое я хотел бы расширить для поддержки нескольких языков с новыми URL-адресами. Например, www.example.com/home.do останется английским, а www.example.com/es/home.do - испанским. Моей первой мыслью было создать фильтр, который перезаписывает входящие URL-адреса типа /es/home.do в /home.do (и устанавливает языковой стандарт в запросе); это прекрасно работает. Фильтр оборачивает 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);

Моя проблема в том, что следующий сервлет не пересылается должным образом. Следующий сервлет (обычно Struts ActionServlet) пересылает JSP (часто с использованием Struts Tiles); когда я перехожу к JSP, HttpServletRequest был обернут несколько раз, и рассматриваемый объект сообщает, что контекст пуст (корневой контекст, в котором фактически развертывается приложение).

Я хочу, чтобы контекст был переписан, чтобы весь мой контекстно-зависимый код, который уже существует, мог автоматически вставлять язык в написанные URL-адреса. Это возможно?

Редактировать: Я решил свою проблему, используя обернутый HttpServletResponse вместо обернутого HttpServletRequest; Я переписываю URL-адрес в методе response.encodeURL ().

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
6 185
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Насколько мне известно, обычный способ сделать это - использовать HTTP-заголовок на принимаемом языке. Язык презентации - это деталь презентации, которая не должна быть представлена ​​набором URL-адресов для навигации по приложению.

Заголовок accept-language не будет работать, потому что он несовместим с поисковыми системами. Поисковым системам нужны уникальные ссылки, чтобы распространять контент на разных языках.

Mr. Shiny and New 安宇 04.11.2008 17:27
Ответ принят как подходящий

Я не уверен, что переопределения getContextPath() достаточно для решения вашей проблемы. Что, если Struts незаметно вызывает ServletContext.getContextPath() или использует getRequestURI() и т. д.?

Я решил свою проблему, выполнив перезапись URL в response.encodeURL () и друзьях. Объект запроса оборачивается и заменяется по всей цепочке запросов, но объект ответа, похоже, не подвергается воздействию. Это работает очень надежно.

Я думаю, что это метод, используемый в проекте UrlRewriterFilter tuckey.org/urlrewrite

Brian Clozel 14.01.2010 10:32

Другие вопросы по теме