应用场景:相当于简易版的nginx
转发控制层,转发所有请求到指定地址
package com.proxy.proxy.demos.web;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@Controller
public class ProxyController {
@Value("${backend.url}")
private String backendUrl;
@Value("${backend.prefix}")
private String prefix;
private final RestTemplate restTemplate = new RestTemplate();
private static final Logger logger = Logger.getLogger(ProxyController.class.getName());
@RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
public ResponseEntity<String> forwardRequest(HttpServletRequest request, @RequestParam Map<String, String> queryParams) throws IOException {
// Convert Map<String, String[]> to MultiValueMap<String, String>
MultiValueMap<String, String> multiValueParams = new LinkedMultiValueMap<>();
// for (Map.Entry<String, String> stringStringEntry : queryParams.entrySet()) {
//
// }
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
// Convert String[] to List<String>
multiValueParams.put(entry.getKey(), Arrays.asList(entry.getValue()));
}
// Construct the URL for the backend service with query parameters
String forwardUrl = UriComponentsBuilder.fromHttpUrl(backendUrl + request.getRequestURI())
.queryParams(multiValueParams)
.toUriString();
// Handle headers
HttpHeaders headers = new HttpHeaders();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
headers.add(headerName, request.getHeader(headerName));
}
// Handle request body (if any)
String requestBody = null;
if (request.getMethod().equalsIgnoreCase("POST") || request.getMethod().equalsIgnoreCase("PUT")) {
requestBody = new BufferedReader(new InputStreamReader(request.getInputStream()))
.lines().collect(Collectors.joining("\n"));
}
// Create HttpEntity with body and headers
HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
//这里前端配有固定前缀需要替换掉,根据自己业务调整
forwardUrl= forwardUrl.replace(prefix, "");
logger.info("Forwarding request to------------------------->: " + forwardUrl);
// Forward the request
ResponseEntity<String> response = restTemplate.exchange(
forwardUrl,
HttpMethod.valueOf(request.getMethod()),
entity,
String.class
);
// Return the response
return ResponseEntity.status(response.getStatusCode())
.headers(response.getHeaders())
.body(response.getBody());
}
}
主启动类:
package com.proxy.proxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class ProxyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ProxyApplication.class);
}
}
配置文件:
# 应用服务 WEB 访问端口
server.port=9999
backend.url=http://127.0.0.1:8099
backend.prefix=/proxy
-------------日志文件配置,转发异常方便排错--------------
# 禁用默认控制台日志输出
logging.pattern.console=
# 启用自定义日志配置文件
logging.config=classpath:logback.xml