import org.apache.commons.io.FileUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
@RestController
public class ProxyController{
// 内网服务器地址+端口
private String targetAddr = "http://10.0.0.100:9000";
/**
* 代理所有请求
*
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "/proxy/**")
public void proxy(HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException {
// String url = URLDecoder.decode(request.getRequestURL().toString(), "UTF-8");
URI uri = new URI(request.getRequestURI());
String path = uri.getPath();
String query = request.getQueryString();
String target = targetAddr + path.replace("/proxy", "");
if (query != null && !query.equals("") && !query.equals("null")) {
target = target + "?" + query;
}
URI newUri = new URI(target);
// 执行代理查询
String methodName = request.getMethod();
HttpMethod httpMethod = HttpMethod.resolve(methodName);
if (httpMethod == null) {
return;
}
InputStream stream = null;
String contentType = request.getContentType();
// 兼容文件上传的请求
if (contentType != null && contentType.startsWith("multipart/form-data")){
MultipartHttpServletRequest mulReq = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> map = mulReq.getFileMap();
List<MultipartFile> valueList = new ArrayList<MultipartFile>(map.values());
MultiValueMap<String, Object> params = new LinkedMultiValueMap();
for (MultipartFile file : valueList) {
File newFile = File.createTempFile("temp",file.getOriginalFilename());
FileUtils.copyInputStreamToFile(file.getInputStream(), newFile);
FileSystemResource resource = new FileSystemResource(newFile);
params.add(file.getName(), resource);
}
RestTemplate restTemplate = new RestTemplate();
// 设置请求头
HttpHeaders headers = new HttpHeaders();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ":" + request.getHeader(headerName));
headers.set(headerName,request.getHeader(headerName));
}
// 手动设置请求头的token信息
headers.set("Authorization",request.getHeader("Authorization"));
// 用HttpEntity封装整个请求报文
HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<MultiValueMap<String, Object>>(params,headers);
String res = restTemplate.postForEntity(target, files, String.class).getBody();
InputStream is =new ByteArrayInputStream(res.getBytes("UTF-8"));
stream = is;
// 其他请求例如get post put delete都可使用
}else {
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);
}));
stream = clientHttpResponse.getBody();
}
// 将获取到的输入流再次输出到页面输出流中
StreamUtils.copy(stream, response.getOutputStream());
}
}
网友评论