我的server.xml配置文件中有tomcat连接器,它应该将所有http流量重定向到https:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector SSLEnabled="true" clientAuth="false" keystoreFile="path/to/keystore/ks.jks" keystorePass="changeit" maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>
如果请求被发送到非安全端口8080,则响应将具有状态代码302.这适用于GET请求,但不适用于POST请求。为什么?因为这些请求是通过RestTemplate
和LaxRedirectStrategy
进行的,如果是302,则将POST转换为GET,这会导致异常“GET不支持...”。一种解决方案可能是扩展LaxRedirectStrategy
并覆盖getRedirect()
方法,如下所示:
LaxRedirectStrategy:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
和我自己的实现(扩展名):
ReLaxRedirectStrategy:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT
|| status == HttpStatus.SC_MOVED_TEMPORARILY) { // HERE IS THE DIFFERENCE
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
我想知道是否有办法让tomcat返回307而不是302以避免代码覆盖以及Apache的httpcomponents将来更新时可能出现的错误。
编辑#1 如果我找不到更好的解决方案,我可能会以ReLaxRedirectStrategy
的第2版结束:
ReLaxRedirectStrategyV2:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final String method = request.getRequestLine().getMethod();
final int status = response.getStatusLine().getStatusCode();
if (method.equalsIgnoreCase(HttpPost.METHOD_NAME)
&& status == HttpStatus.SC_MOVED_TEMPORARILY) {
final URI uri = getLocationURI(request, response, context);
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return super.getRedirect(request, response, context);
}
}
这种覆盖代码是最小的。如果对POST请求的响应具有状态302,则代码将执行我想要的操作,否则它将执行超类中定义的任何操作。