package com.ard.web.controller.sample.media;
|
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.http.*;
|
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 javax.servlet.http.HttpServletRequest;
|
import java.io.IOException;
|
import java.net.URI;
|
import java.net.URLDecoder;
|
import java.nio.charset.StandardCharsets;
|
import java.util.Collections;
|
import java.util.Enumeration;
|
|
@Slf4j
|
@Api(tags = "机场上传minio")
|
@RestController
|
@RequestMapping("/minioTransfer")
|
public class MinioGeneralProxyController {
|
|
@Value("${oss.endpoint}")
|
private String minioServerEndpoint;
|
|
private final RestTemplate restTemplate;
|
private static final String BASE_PREFIX = "/minioTransfer";
|
|
public MinioGeneralProxyController(RestTemplate restTemplate) {
|
this.restTemplate = restTemplate;
|
}
|
|
@ApiOperation("MinIO原生接口代理(无感中转)")
|
@RequestMapping(value = "/**")
|
public ResponseEntity<byte[]> proxyAllRequest(HttpServletRequest request) {
|
try {
|
// 1. 解析请求基础信息
|
String methodStr = request.getMethod();
|
String rawUri = URLDecoder.decode(request.getRequestURI(), StandardCharsets.UTF_8);
|
String queryString = request.getQueryString();
|
|
log.info("转发请求 | 方法:{} | URI:{} | 参数:{}", methodStr, rawUri, queryString);
|
|
// 2. 构建MinIO目标地址
|
String targetPath = rawUri.substring(BASE_PREFIX.length());
|
StringBuilder targetUrl = new StringBuilder(minioServerEndpoint);
|
targetUrl.append(targetPath);
|
if (queryString != null && !queryString.isBlank()) {
|
targetUrl.append("?").append(queryString);
|
}
|
URI uri = URI.create(targetUrl.toString());
|
|
// 3. 转换为Spring标准HttpMethod(核心修复点)
|
HttpMethod httpMethod = HttpMethod.valueOf(methodStr);
|
|
// 4. 复制请求头+请求体
|
HttpHeaders headers = copyRequestHeaders(request);
|
byte[] requestBody = extractRequestBody(request);
|
HttpEntity<byte[]> requestEntity = new HttpEntity<>(requestBody, headers);
|
|
// 5. 修复exchange方法调用,匹配Spring官方重载方法
|
ResponseEntity<byte[]> response = restTemplate.exchange(
|
uri,
|
httpMethod,
|
requestEntity,
|
byte[].class
|
);
|
|
log.info("转发成功 | 目标地址:{} | 状态码:{}", targetUrl, response.getStatusCode());
|
// 原样回传所有响应信息
|
return new ResponseEntity<>(
|
response.getBody(),
|
response.getHeaders(),
|
response.getStatusCode()
|
);
|
|
} catch (Exception e) {
|
log.error("代理转发执行异常", e);
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
.body(("代理服务异常:" + e.getMessage()).getBytes(StandardCharsets.UTF_8));
|
}
|
}
|
|
/**
|
* 透传所有请求头
|
*/
|
private HttpHeaders copyRequestHeaders(HttpServletRequest request) {
|
HttpHeaders headers = new HttpHeaders();
|
Enumeration<String> headerNames = request.getHeaderNames();
|
if (headerNames == null) {
|
return headers;
|
}
|
while (headerNames.hasMoreElements()) {
|
String name = headerNames.nextElement();
|
Enumeration<String> values = request.getHeaders(name);
|
headers.addAll(name, Collections.list(values));
|
}
|
// 移除Host头,避免转发地址冲突
|
headers.remove(HttpHeaders.HOST);
|
return headers;
|
}
|
|
/**
|
* 读取请求体数据
|
*/
|
private byte[] extractRequestBody(HttpServletRequest request) {
|
try {
|
return StreamUtils.copyToByteArray(request.getInputStream());
|
} catch (IOException e) {
|
log.warn("读取请求体失败", e);
|
return new byte[0];
|
}
|
}
|
}
|