spring-bootはインターフェースフォワーディングサービスを実現し、getやpostなどの様々なリクエストを同時にサポートします
(1) 新しいクラス: 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) コードの説明:
これは という名前の Java クラスですProxyController
。コードには次のメソッドが含まれています。
handleRequest(HttpServletRequest request)
これは戻り値の型が のパブリック メソッドでありResponseEntity<String>
、いくつかの例外をスローする可能性があります。このメソッドの目的は、HTTP リクエストを処理し、受信リクエスト オブジェクトに従って対応する応答を返すことです。このメソッドは@RequestMapping("/dahua/**")
注釈によってマークされています。これは、/proxy/dahua
このメソッドが URL に が含まれている場合にのみ呼び出されることを意味します。このメソッドは、受信リクエストを別の URL に転送し、応答を返す機能を実装します。リクエストが GET または POST ではない場合、エラー応答が返されます。
getPath(HttpServletRequest request)
これは、戻り値の型が のプライベート メソッドですString
。このメソッドはリクエスト オブジェクトを受け取り、そこからコンテキスト パス、サーブレット パス、およびパス情報を取得し、それらを結合して完全な URL パスを返します。
getRequestHeaders(HttpServletRequest request)
これは、戻り値の型が のプライベート メソッドですHttpHeaders
。このメソッドはリクエスト オブジェクトを取得し、そこからすべてのリクエスト ヘッダーをフェッチし、それらを新しいHttpHeaders
オブジェクトに入れて、そのオブジェクトを返します。
getRequestBody(HttpServletRequest request)
これは戻り値の型が のプライベート メソッドでありString
、IO 例外をスローする可能性があります。このメソッドはリクエスト オブジェクトを受け取り、そこからリクエスト本文 (存在する場合) を取得し、それを文字列に変換して、その文字列を返します。
getSecureHttpRequestFactory()
これは戻り値の型が のプライベート メソッドでありHttpComponentsClientHttpRequestFactory
、いくつかの例外をスローする可能性があります。このメソッドの目的は、HTTPS 経由で別の URL に接続できるようにする安全な HTTP リクエスト ファクトリを作成することです。このメソッドは、TrustManager
と を使用しSSLContext
てすべての証明書の信頼を実装し、それをリクエスト ファクトリ内の SSL ソケット ファクトリとして設定し、そのリクエスト ファクトリを返します。
それに加えて、コードにはいくつかの注釈と変数宣言も含まれています。このうち@ApiOperation
アノテーションは、メソッドが動作指示情報を持っていることを示し、@RequestMapping("/dahua/**")
URL に が含まれる場合にのみメソッドが呼び出されることを示します/proxy/dahua
。変数method
、path
、targetUri
、headers
、entity
、restTemplate
、postEntity
などrequestFactory
は、コード内で対応する用途を持っています。