springboot web 接口转发http或https请求
请求地址:http://localhost:8080/proxy/http://192.168.12.103:8702/user/getUsers
目标地址:http://192.168.12.103:8702/user/getUsers
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
@Tag(name = "代理转发接口")
@RestController
public class ProxyController {
/**
* 代理所有请求
*/
@RequestMapping(value = "/proxy/**")
public void proxy(HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException {
URI uri = new URI(request.getRequestURI());
String path = uri.getPath();
String query = request.getQueryString();
String target = path.replace("/proxy/", "");
if (query != null && !query.isEmpty() && !query.equals("null")) {
target = target + "?" + query;
}
URI newUri = new URI(completeUrl(target));
// 执行代理查询
String methodName = request.getMethod();
HttpMethod httpMethod = HttpMethod.resolve(methodName);
if (httpMethod == null) {
return;
}
ClientHttpRequest delegate = new SimpleClientHttpRequestFactory().createRequest(newUri, httpMethod);
Enumeration<String> headerNames = request.getHeaderNames();
// 设置请求头
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
Enumeration<String> v = request.getHeaders(headerName);
List<String> arr = new ArrayList<>();
while (v.hasMoreElements()) {
arr.add(v.nextElement());
}
delegate.getHeaders().addAll(headerName, arr);
}
StreamUtils.copy(request.getInputStream(), delegate.getBody());
// 执行远程调用
ClientHttpResponse clientHttpResponse = delegate.execute();
response.setStatus(clientHttpResponse.getStatusCode().value());
// 设置响应头
clientHttpResponse.getHeaders().forEach((key, value) -> value.forEach(it -> response.setHeader(key, it)));
StreamUtils.copy(clientHttpResponse.getBody(), response.getOutputStream());
}
/**
* 确保URL的协议部分以正确的格式开始。如果URL以"http:/"或"https:/"开头但不是以"http://"或"https://"开头,则将其替换为正确的格式。
*/
public static String completeUrl(String url) {
if (url == null) {
throw new IllegalArgumentException("URL cannot be null.");
}
url = ensureProtocolPrefix(url, "http:");
url = ensureProtocolPrefix(url, "https:");
return url;
}
/**
* 确保URL以指定的协议前缀开始。如果URL以给定协议的不完整版本开头(例如"http:/"而不是"http://"),则将其替换为正确的格式。
*/
private static String ensureProtocolPrefix(String url, String protocol) {
String correctedUrl = url;
if (!url.startsWith(protocol + "//") && url.startsWith(protocol + "/")) {
correctedUrl = url.replaceFirst(protocol + "/", protocol + "//");
}
return correctedUrl;
}
}