spring-boot realiza el servicio de reenvío de interfaz y admite varias solicitudes, como obtener y publicar al mismo tiempo
(1) Nueva clase: ProxyController.java
package com.taobao.product.controller;
import com.taobao.framework.HttpResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.net.URISyntaxException;
import java.util.Enumeration;
import org.springframework.http.MediaType;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
/**
* @Author: sunkaiyuan
* @Date: 2023-05-23 9:02
* @Desperation: TODO
*/
@Api(tags = "代理服务")
@RestController
@RequestMapping("/proxy")
@Slf4j
public class ProxyController {
@ApiOperation(value = "接口转发")
@RequestMapping("/dahua/**")
public ResponseEntity<String> handleRequest(HttpServletRequest request) throws IOException, URISyntaxException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
String method = request.getMethod();
String path = getPath(request);
// 去掉url中的/proxy/dahua
path = path.substring(request.getContextPath().length() + "/proxy/dahua".length());
URI targetUri = new URI("https://121.26.142.174:8443" + path);
System.out.println(targetUri);
HttpHeaders headers = getRequestHeaders(request);
HttpEntity<?> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate(getSecureHttpRequestFactory());
if (method.equalsIgnoreCase(HttpMethod.GET.name())) {
return restTemplate.exchange(targetUri, HttpMethod.GET, entity, String.class);
} else if (method.equalsIgnoreCase(HttpMethod.POST.name())) {
String requestBody = getRequestBody(request);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> postEntity = new HttpEntity<>(requestBody, headers);
return restTemplate.exchange(targetUri, HttpMethod.POST, postEntity, String.class);
} else {
return ResponseEntity.badRequest().body("Unsupported request method: " + method);
}
}
private String getPath(HttpServletRequest request) {
String contextPath = request.getContextPath();
String servletPath = request.getServletPath();
String pathInfo = request.getPathInfo() != null ? request.getPathInfo() : "";
return contextPath + servletPath + pathInfo;
}
private HttpHeaders getRequestHeaders(HttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
List<String> headerValues = Collections.list(request.getHeaders(headerName));
headers.put(headerName, headerValues);
}
return headers;
}
private String getRequestBody(HttpServletRequest request) throws IOException {
return request.getReader().lines().reduce("", (accumulator, actual) -> accumulator + actual);
}
private HttpComponentsClientHttpRequestFactory getSecureHttpRequestFactory() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
}
} };
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, null);
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(HttpClients.custom().setSSLSocketFactory(csf).build());
return requestFactory;
}
}
(2) Descripción del código:
Esta es una clase Java llamada ProxyController
. El código contiene los siguientes métodos:
handleRequest(HttpServletRequest request)
Este es un método público con un tipo de retorno de ResponseEntity<String>
, que genera algunas posibles excepciones. El propósito de este método es procesar la solicitud HTTP y devolver la respuesta correspondiente según el objeto de la solicitud entrante. Este método está @RequestMapping("/dahua/**")
marcado por la anotación, lo que significa que /proxy/dahua
este método se llamará solo cuando la URL contenga. Este método implementa la funcionalidad de reenviar una solicitud entrante a otra URL y devolver una respuesta. Si la solicitud no es GET o POST, se devuelve una respuesta de error.
getPath(HttpServletRequest request)
Este es un método privado con un tipo de retorno de String
. Este método recibe un objeto de solicitud, obtiene la ruta de contexto, la ruta del servlet y la información de la ruta, las combina en una ruta de URL completa y la devuelve.
getRequestHeaders(HttpServletRequest request)
Este es un método privado con un tipo de retorno de HttpHeaders
. Este método toma un objeto de solicitud, obtiene todos los encabezados de solicitud, los coloca en un nuevo HttpHeaders
objeto y devuelve ese objeto.
getRequestBody(HttpServletRequest request)
Este es un método privado con un tipo de retorno de String
, que puede generar una excepción de E/S. Este método toma un objeto de solicitud, obtiene el cuerpo de la solicitud (si lo hay), lo convierte en una cadena y devuelve esa cadena.
getSecureHttpRequestFactory()
Este es un método privado con un tipo de devolución de HttpComponentsClientHttpRequestFactory
, que puede generar algunas excepciones. El propósito de este método es crear una fábrica de solicitudes HTTP segura que nos permita conectarnos a otra URL a través de HTTPS. Este método utiliza TrustManager
e SSLContext
implementa la confianza en todos los certificados, lo establece como la fábrica de sockets SSL en la fábrica de solicitudes y devuelve esa fábrica de solicitudes.
Además de eso, el código también contiene algunas anotaciones y declaraciones de variables. Entre ellos, @ApiOperation
la anotación indica que el método tiene información de instrucciones de operación; @RequestMapping("/dahua/**")
indica que el método se llamará solo cuando la URL contenga /proxy/dahua
. Las variables method
, path
, targetUri
, headers
, entity
, restTemplate
, postEntity
, requestFactory
etc. tienen usos correspondientes en el código.