Поведение вашего кода правильное, потому что вы говорите, что ваш URL-адрес редиректа относителен к контексту, но это должен быть действительный URL-адрес, и по этой причине Spring построил его как URL-адрес, /my/page.html не является действительный URL. сказал, что проблема заключается в том, что вы должны настроить перезапись URL-адреса в полнодуплексном режиме и устранить проблему в обратном прокси-сервере, фактически для предполагаемого кода, если он выполняется на сервере, который обслуживает порт 80, код отобразит ваш URL-адрес. на 80 в противном случае вы должны написать свой URL вручную, как показано ниже:
@RequestMapping(method = RequestMethod.GET, value = "/")
public RedirectView localRedirect()
{
final RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://localhost:8080/my/index.html");
redirectView.setHosts();
return redirectView;
}
Я попытался запустить два экземпляра приложения на моем компьютере, один на 80, а другой на 8080, и перенаправления работают правильно
Обновление:
когда вы используете RedirectView, перенаправление происходит на стороне сервера с помощью вызова HttpServletResponse.sendRedirect, конечно, если ваш сервер остается за обратным прокси, ваше приложение на стороне сервера может этого не знать.
Когда вы используете в заголовке Location Location заголовок, это обычная строка, не переходящая из среды вашего сервлета. В вашем браузере происходит перенаправление, которое в этом случае получает относительный URL, потому что в вашем контроллере вы задаете простую строку, и ваш браузер уже знает сервер, который уже проксирован.
Update2
Основная логика класса RedirectView - это защищенный метод, называемый sendRedirect (...).
/**
* Send a redirect back to the HTTP client
* @param request current HTTP request (allows for reacting to request method)
* @param response current HTTP response (for sending response headers)
* @param targetUrl the target URL to redirect to
* @param http10Compatible whether to stay compatible with HTTP 1.0 clients
* @throws IOException if thrown by response methods
*/
protected void sendRedirect(HttpServletRequest request, HttpServletResponse response,
String targetUrl, boolean http10Compatible) throws IOException {
String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl));
if (http10Compatible) {
HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE);
if (this.statusCode != null) {
response.setStatus(this.statusCode.value());
response.setHeader("Location", encodedURL);
}
else if (attributeStatusCode != null) {
response.setStatus(attributeStatusCode.value());
response.setHeader("Location", encodedURL);
}
else {
// Send status code 302 by default.
response.sendRedirect(encodedURL);
}
}
else {
HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
response.setStatus(statusCode.value());
response.setHeader("Location", encodedURL);
}
}
метод сначала извлекает URL, а затем, если http10Compatible имеет значение true, в конечном итоге будет использовать response.sendRedirect (encodedURL); в противном случае просто поместите ваш относительный URL в заголовок местоположения без пропуска для API сервлета. В вашем коде вы не предоставляете данные для активного условия if, которое предотвращает sendRedirect Servlet api. Это может объяснить, почему в вашем коде у вас есть проблемы. Конечно, в любой другой ветви кода: http10Compatible в false и т. Д. В вашем коде просто поместите строку в заголовок Location, и это работает, потому что в вашем браузере, который будет выполнять перенаправление, поступает относительный URL.
На вопрос, является ли это ошибкой Servlet API, я могу поставить официальный код интерфейса:
HttpServletResponse.java:
/**
* Sends a temporary redirect response to the client using the specified
* redirect location URL. This method can accept relative URLs; the servlet
* container must convert the relative URL to an absolute URL before sending
* the response to the client. If the location is relative without a leading
* '/' the container interprets it as relative to the current request URI.
* If the location is relative with a leading '/' the container interprets
* it as relative to the servlet container root.
* <p>
* If the response has already been committed, this method throws an
* IllegalStateException. After using this method, the response should be
* considered to be committed and should not be written to.
*
* @param location
* the redirect location URL
* @exception IOException
* If an input or output exception occurs
* @exception IllegalStateException
* If the response was committed or if a partial URL is given
* and cannot be converted into a valid URL
*/
public void sendRedirect(String location) throws IOException;
Вы можете прочитать фрагмент комментария:
This method can accept relative URLs; the servlet
* container must convert the relative URL to an absolute URL before sending
* the response to the client
Читая его, я могу сказать, что это не ошибка, а особенность API сервлета, которая, тем не менее, ставит единственный серверный сервер, который сам знает, и по этой причине он не работает с прокси-сервером реверса.
Я надеюсь, что это может хорошо объяснить проблему.