你可以實現doFilter
這樣一個Servlet過濾器做到這一點:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
String protocol = req.getHeader("X-Forwarded-Proto");
if (protocol.equals("http")) {
String url = "https://" + req.getServerName() + req.getContextPath() + req.getServletPath();
if (req.getPathInfo() != null) {
url += req.getPathInfo();
}
System.out.println("Forwarding request to: " + url);
resp.sendRedirect(url);
} else {
System.out.println("Not forwarding protocol: " + protocol);
chain.doFilter(request, response);
}
}
這裏的a complete example using Tomcat,但原理是一樣的。
謝謝@codefinger。在使用Chrome時,X-Forwarded-Proto不包括在標題中,所以這對我不起作用。但是,我發現HttpServletRequest.getScheme()似乎能夠正確識別我是使用HTTP還是HTTPS,所以我會嘗試這種方法併發布結果。 –
好的,調查後發現:HttpServletRequest.getScheme()不可靠(即使在Heroku上使用HTTPS時也會返回「http」),並且HttpServletRequest.isSecure()也不可靠(在Heroku上使用HTTPS時返回false )。 X-Forwarded-Proto標頭不會發送到本地運行的服務器,而是發送到在Heroku上運行的服務器。這個答案是正確的。 –
我相信麻煩w/getScheme是因爲SSL終止發生在Heroku路由器(因此連接是HTTP在Servlet)。最好檢查兩個? – codefinger