import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
@Controller
public class ProxyController {
//TARGET_URL为需要代理的目标接口地址
private static final String TARGET_URL = "http://localhost:8080";
private static final Set<String> HOP_BY_HOP;
static {
disableCertificateValidation();
Set<String> skipHeaders = new HashSet<>();
skipHeaders.add("connection");
skipHeaders.add("keep-alive");
skipHeaders.add("proxy-authenticate");
skipHeaders.add("proxy-authorization");
skipHeaders.add("te");
skipHeaders.add("trailers");
skipHeaders.add("transfer-encoding");
skipHeaders.add("upgrade");
skipHeaders.add("host");
HOP_BY_HOP = Collections.unmodifiableSet(skipHeaders);
}
private static void disableCertificateValidation() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = (hostname, session) -> true;
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/proxyApi/**")
public void proxy(HttpServletRequest request, HttpServletResponse response) throws IOException {
String base = TARGET_URL.trim();
if (base.endsWith("/")) {
base = base.substring(0, base.length() - 1);
}
String uri = request.getRequestURI();
String ctx = request.getContextPath();
String path = uri.startsWith(ctx) ? uri.substring(ctx.length()) : uri;
StringBuilder targetUrl = new StringBuilder(base).append(path);
String query = request.getQueryString();
if (query != null) {
targetUrl.append("?").append(query);
}
URL url = new URL(targetUrl.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
try {
String method = request.getMethod();
conn.setRequestMethod(method);
conn.setDoInput(true);
boolean hasBody = "POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method);
conn.setDoOutput(hasBody);
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String lower = name.toLowerCase();
if (HOP_BY_HOP.contains(lower)) {
continue;
}
if (hasBody && ("content-length".equals(lower) || "transfer-encoding".equals(lower))) {
continue;
}
Enumeration<String> values = request.getHeaders(name);
while (values.hasMoreElements()) {
conn.addRequestProperty(name, values.nextElement());
}
}
if (hasBody) {
try (InputStream in = request.getInputStream();
OutputStream out = conn.getOutputStream()) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
}
int status = conn.getResponseCode();
response.setStatus(status);
for (String key : conn.getHeaderFields().keySet()) {
if (key == null || HOP_BY_HOP.contains(key.toLowerCase())) {
continue;
}
response.setHeader(key, conn.getHeaderField(key));
}
try (InputStream in = conn.getInputStream();
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
}
}
springboot反向代理Controller实现
于 2026-05-07 14:01:38 首次发布
5411

被折叠的 条评论
为什么被折叠?



