RestTemplate
工具类:
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
/**
* @author qhong
* @date 2021/08/30 10:02
**/
@Service
public class RoutingDelegate {
public ResponseEntity<String> redirect(HttpServletRequest request, HttpServletResponse response,String routeUrl, String prefix) {
try {
// build up the redirect URL
String redirectUrl = createRedictUrl(request,routeUrl, prefix);
RequestEntity requestEntity = createRequestEntity(request, redirectUrl);
return route(requestEntity);
} catch (Exception e) {
return new ResponseEntity("REDIRECT ERROR", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
private String createRedictUrl(HttpServletRequest request, String routeUrl, String prefix) {
String queryString = request.getQueryString();
return routeUrl + request.getRequestURI().replace(prefix, "") +
(queryString != null ? "?" + queryString : "");
}
private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException {
String method = request.getMethod();
HttpMethod httpMethod = HttpMethod.resolve(method);
MultiValueMap<String, String> headers = parseRequestHeader(request);
byte[] body = parseRequestBody(request);
return new RequestEntity<>(body, headers, httpMethod, new URI(url));
}
private ResponseEntity<String> route(RequestEntity requestEntity) {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.exchange(requestEntity, String.class);
}
private byte[] parseRequestBody(HttpServletRequest request) throws IOException {
InputStream inputStream = request.getInputStream();
return StreamUtils.copyToByteArray(inputStream);
}
private MultiValueMap<String, String> parseRequestHeader(HttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
List<String> headerNames = Collections.list(request.getHeaderNames());
for (String headerName : headerNames) {
List<String> headerValues = Collections.list(request.getHeaders(headerName));
for (String headerValue : headerValues) {
headers.add(headerName, headerValue);
}
}
return headers;
}
}
Spring集成:
@RestController
@RequestMapping(GraphDBController.DELEGATE_PREFIX)
@Api(value = "GraphDB", tags = {
"graphdb-Api"
})
public class GraphDBController {
@Autowired
GraphProperties graphProperties;
public final static String DELEGATE_PREFIX = "/graphdb";
@Autowired
private RoutingDelegate routingDelegate;
@RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity catchAll(HttpServletRequest request, HttpServletResponse response) {
return routingDelegate.redirect(request, response, graphProperties.getGraphServer(), DELEGATE_PREFIX);
}
}
OKHttp3
工具类:
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StreamUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;
/**
* Created by qhong on 2018/7/3 16:55
**/
public class OkHttpUtil {
private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);
/**
* 调用okhttp的newCall方法
*
* @param request
* @return
*/
private static String execNewCall(Request request) {
Response response = null;
try {
OkHttpClient okHttpClient = SpringUtils.getBean(OkHttpClient.class);
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 put error >> ex = {}", e);
} finally {
if (response != null) {
response.close();
}
}
return "";
}
/**
* 代理转发请求
*
* @param request
* @return
*/
public static String route(String routeUrl, String prefix, HttpServletRequest request) {
try {
String redirectUrl = createRedictUrl(request, routeUrl, prefix);
Map<String, String> header = getOriginHeader(request);
InputStream inputStream = request.getInputStream();
String body = StreamUtils.copyToString(inputStream, Charset.defaultCharset());
return postJsonParams(redirectUrl, header, body);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* get
*
* @param url 请求的url
* @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
* @return
*/
public static String get(String url, Map<String, String> queries) {
StringBuffer sb = getQueryString(url, queries);
Request request = new Request.Builder()
.url(sb.toString())
.build();
return execNewCall(request);
}
/**
* post
*
* @param url 请求的url
* @param params post form 提交的参数
* @return
*/
public static String postFormParams(String url, Map<String, String> params) {
return postFormParams(url, null, params);
}
/**
* post x-www-form-urlencoded
*
* @param url 请求的url
* @param heads head参数
* @param params post form 提交的参数
* @return
*/
public static String postFormParams(String url, Map<String, String> heads, Map<String, String> params) {
FormBody.Builder builder = new FormBody.Builder();
//添加参数
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
builder.add(key, params.get(key));
}
}
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.headers(SetHeaders(heads))
.build();
return execNewCall(request);
}
/**
* post form-data
*
* @param url 请求的url
* @param heads head参数
* @param params post form 提交的参数
* @return
*/
public static String postFormDataParams(String url, Map<String, String> heads,
Map<String, String> params) {
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
//添加参数
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
builder.addFormDataPart(key, params.get(key));
}
}
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.headers(SetHeaders(heads))
.build();
return execNewCall(request);
}
/**
* Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
* 参数一:请求Url
* 参数二:请求的JSON
* 参数三:请求回调
*/
public static String postJsonParams(String url, String jsonParams) {
return postJsonParams(url, null, jsonParams);
}
/**
* Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
* 参数一:请求Url
* 参数二:请求的JSON
* 参数三:请求回调
*/
public static String postJsonParams(String url, Map<String, String> heads, String jsonParams) {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.headers(SetHeaders(heads))
.build();
return execNewCall(request);
}
/**
* Post请求发送xml数据....
* 参数一:请求Url
* 参数二:请求的xmlString
* 参数三:请求回调
*/
public static String postXmlParams(String url, String xml) {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
return execNewCall(request);
}
//***************************************************内部方法******************************************//
/**
* 根据map获取get请求参数
*
* @param queries
* @return
*/
private static StringBuffer getQueryString(String url, Map<String, String> queries) {
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
return sb;
}
/**
* header参数
*
* @param headersParams
* @return
*/
private static Headers SetHeaders(Map<String, String> headersParams) {
Headers headers = null;
okhttp3.Headers.Builder headersbuilder = new okhttp3.Headers.Builder();
if (headersParams != null && !headersParams.isEmpty()) {
Iterator<String> iterator = headersParams.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next().toString();
headersbuilder.add(key, headersParams.get(key));
}
}
headers = headersbuilder.build();
return headers;
}
private static String createRedictUrl(HttpServletRequest request, String routeUrl, String prefix) {
String queryString = request.getQueryString();
return routeUrl + request.getRequestURI().replace(prefix, "") +
(queryString != null ? "?" + queryString : "");
}
/**
* 获取请求体的header参数
*
* @param request
*/
private static Map<String, String> getOriginHeader(HttpServletRequest request) {
Map<String, String> headers = new HashMap<>();
List<String> headerNames = Collections.list(request.getHeaderNames());
for (String headerName : headerNames) {
List<String> headerValues = Collections.list(request.getHeaders(headerName));
for (String headerValue : headerValues) {
if (!headerName.equalsIgnoreCase("host")) {
headers.put(headerName, headerValue);
}
}
}
return headers;
}
}
Spring集成
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(NanoRoutingController.DELEGATE_PREFIX)
@Api(value = "nano代理")
public class NanoRoutingController {
@Value("${rpc.nano.host:http://94343-test.net}")
private String host;
public static final String DELEGATE_PREFIX = "/nano";
@RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE},
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity catchAll(HttpServletRequest request) {
String result = OkHttpUtil.route(host, DELEGATE_PREFIX, request);
return ResponseEntity.ok(result);
}
}
参考:
spring boot实现超轻量级网关(反向代理、转发)