Как получить имя хоста с портом из запроса http или https

У меня есть два приложения, развернутые в контейнере jboss (тот же самый блок unix). Если я получаю запрос от app1, мне нужно создать соответствующий запрос для app2.

, например:
если запрос app1: http://example.com/context?param1=123
то мне нужно извлечь " http://example.com/", чтобы я мог запросить кадр для второго приложения.

Я попытался использовать:

  HttpServletRequest.getServerName() & 
  HttpServletRequest.getServerPort() & \
  HttpServletRequest.getHeader("host") 

но запрос может быть http или https.

Пожалуйста, дайте мне знать, есть ли другой лучший способ. Спасибо!

Ответы

Ответ 1

Вы можете использовать HttpServletRequest.getScheme() для получения "http" или "https".

Использовать его вместе с HttpServletRequest.getServerName() должно быть достаточно, чтобы перестроить часть URL-адреса, который вам нужен.

Вам не нужно явно указывать порт в URL-адресе, если вы используете стандартные (80 для http и 443 для https).

Изменить. Если ваш контейнер сервлета находится за обратным прокси-сервером или балансиром нагрузки, который завершает SSL, это немного сложнее, потому что запросы перенаправляются в контейнер сервлета как простой http. У вас есть несколько вариантов:

1) Вместо этого используйте HttpServletRequest.getHeader("x-forwarded-proto"); это работает только в том случае, если ваш балансировочный балансир правильно устанавливает заголовок (Apache должен afaik).

2) Настройте RemoteIpValve в JBoss/Tomcat, что сделает getScheme() работать должным образом. Опять же, это будет работать, только если балансировщик нагрузки задает правильные заголовки.

3) Если вышеуказанное не работает, вы можете настроить два разных коннектора в Tomcat/JBoss, один для http и один для https, как описано в этой статьи.

Ответ 3

Если вы используете балансировщик нагрузки и Nginx, настройте их без кода изменения.

Nginx:

proxy_set_header       Host $host;  
proxy_set_header  X-Real-IP  $remote_addr;  
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;  
proxy_set_header X-Forwarded-Proto  $scheme;  

Tomcat server.xml Двигатель:

<Valve className="org.apache.catalina.valves.RemoteIpValve"  
remoteIpHeader="X-Forwarded-For"  
protocolHeader="X-Forwarded-Proto"  
protocolHeaderHttpsValue="https"/> 

Если только изменить конфигурационный файл Nginx, код java должен быть:

String XForwardedProto = request.getHeader("X-Forwarded-Proto");

Ответ 4

Если вы хотите, чтобы исходный URL-адрес просто использовал метод, описанный jthalborn. Если вы хотите перестроить URL-адрес, как объяснил Дэвид Левеске, вот фрагмент кода для него:

final javax.servlet.http.HttpServletRequest req = (javax.servlet.http.HttpServletRequest) ...;
final int serverPort = req.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
  // No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
  url = String.format("%s://%s/...", req.getScheme(), req.getServerName(), ...);
} else {
  url = String.format("%s://%s:%s...", req.getScheme(), req.getServerName(), serverPort, ...);
}

Вам все равно нужно рассмотреть случай обратного прокси:

Можно использовать константы для портов, но не уверен, есть ли у них надежный источник, порты по умолчанию:

Большинство разработчиков будут знать о портах 80 и 443 в любом случае, поэтому константы не так полезны.

Также см. этот пост.