001package io.jboot.web.render; 002 003import com.jfinal.kit.StrKit; 004import com.jfinal.render.RedirectRender; 005 006/** 007 * RedirectRender with status: 302 Found. 008 * 009 * 010 * 注意:使用 nginx 代理实现 https 的场景,解决 https 被重定向到了 http 的问题,需要在 nginx 中添加如下配置: 011 * proxy_set_header X-Forwarded-Proto $scheme; 012 * proxy_set_header X-Forwarded-Port $server_port; 013 * 014 * 015 * PS:nginx 将 http 重定向到 https 的配置为: 016 * proxy_redirect http:// https://; 017 * 注意: 需要同时支持 http 与 https 的场景不能使用该配置 018 * 019 */ 020public class JbootRedirectRender extends RedirectRender { 021 022 public JbootRedirectRender(String url) { 023 super(url); 024 } 025 026 public JbootRedirectRender(String url, boolean withQueryString) { 027 super(url, withQueryString); 028 } 029 030 @Override 031 public String buildFinalUrl() { 032 String ret; 033 // 如果一个url为/login/connect?goto=http://www.jfinal.com,则有错误 034 // ^((https|http|ftp|rtsp|mms)?://)$ ==> indexOf 取值为 (3, 5) 035 if (contextPath != null && (url.indexOf("://") == -1 || url.indexOf("://") > 5)) { 036 ret = contextPath + url; 037 } else { 038 ret = url; 039 } 040 041 if (withQueryString) { 042 String queryString = request.getQueryString(); 043 if (queryString != null) { 044 if (ret.indexOf('?') == -1) { 045 ret = ret + "?" + queryString; 046 } else { 047 ret = ret + "&" + queryString; 048 } 049 } 050 } 051 052 // 跳过 http/https 已指定过协议类型的 url,用于支持跨域名重定向 053 if (ret.toLowerCase().startsWith("http")) { 054 return ret; 055 } 056 057 /** 058 * 注意:nginx 代理 https 的场景,需要使用如下配置: 059 * proxy_set_header X-Forwarded-Proto $scheme; 060 * proxy_set_header X-Forwarded-Port $server_port; 061 */ 062 if ("https".equalsIgnoreCase(request.getHeader("X-Forwarded-Proto"))) { 063 String serverName = request.getServerName(); 064 065 /** 066 * 获取 nginx 端通过配置 proxy_set_header X-Forwarded-Port $server_port; 067 * 传递过来的端口号,保障重定向时端口号是正确的 068 */ 069 String port = request.getHeader("X-Forwarded-Port"); 070 if (StrKit.notBlank(port)) { 071 serverName = serverName + ":" + port; 072 } 073 074 if (ret.charAt(0) != '/') { 075 return "https://" + serverName + "/" + ret; 076 } else { 077 return "https://" + serverName + ret; 078 } 079 080 } else { 081 return ret; 082 } 083 } 084} 085 086 087 088 089 090 091 092