oldwu's Blog - 反向代理
type: channel
link: https://blog.oldwu.top/index.php/tag/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/
items: 使用Java实现类似nginx的转发请求

使用Java实现类似nginx的转发请求
type: item
date: 2022-01-05T08:40:30+08:00
description: 因为需要将应用服务器之外的另一台文件服务器的ip地址隐藏，并且需要记录文件访问记录，以及需要对request的请求做一些处理，nginx实现这些相当麻烦，因此直接用Java写一个反向代理，简单明了。utils相当于使用流拷贝的方式，将获取到的newUrl的response，拷贝到客户请求的response中，这样就实现了转发 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; public class ProxyUtil { public static void proxy(URI newUri, HttpServletRequest request, HttpServletResponse response) throws IOException { 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()); } }controller//经过/proxy/**的地址都会返回192.168.1.1的结果，相当于nginx反向代理的效果 @RequestMapping(value = "/proxy/**") public void proxy(HttpServletRequest request, HttpServletResponse response){ String path = uri.getPath(); URI…