调整依赖,完善远程调用功能

This commit is contained in:
wanggeng 2021-09-19 23:36:45 +08:00
parent d1223da19c
commit 71195a026f
6 changed files with 364 additions and 99 deletions

View File

@ -152,13 +152,6 @@
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- wgink end -->
<!-- cglib start -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
<!-- cglib end -->
</dependencies>
</project>

View File

@ -1,45 +0,0 @@
package ink.wgink.util.remote.rest;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @ClassName: RestRemoteRequest
* @Description: rest远程请求
* @Author: wanggeng
* @Date: 2021/9/18 4:23 下午
* @Version: 1.0
*/
public class RestRemoteRequestDemo implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, args);
}
public static class RestRemoteRequestFactory {
public static Object getProxy(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(clazz.getClassLoader());
enhancer.setSuperclass(clazz);
enhancer.setCallback(new RestRemoteRequestDemo());
return enhancer.create();
}
}
public static class Demo {
void say(String msg) {
System.out.println(msg);
}
}
public static void main(String[] args) {
Demo demo = (Demo) RestRemoteRequestFactory.getProxy(Demo.class);
demo.say("你好");
}
}

View File

@ -1,9 +1,22 @@
package ink.wgink.util.remote.rest.handler;
import ink.wgink.annotation.remote.RemoteServer;
import ink.wgink.annotation.remote.method.RemoteDeleteMethod;
import ink.wgink.annotation.remote.method.RemoteGetMethod;
import ink.wgink.annotation.remote.method.RemotePostMethod;
import ink.wgink.annotation.remote.method.RemotePutMethod;
import ink.wgink.annotation.remote.params.RemoteHeaderParams;
import ink.wgink.annotation.remote.params.RemoteJsonBodyParams;
import ink.wgink.annotation.remote.params.RemotePathParams;
import ink.wgink.annotation.remote.params.RemoteQueryParams;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.util.RegexUtil;
import ink.wgink.util.remote.rest.request.RestRemoteRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationHandler;
@ -25,7 +38,7 @@ import java.util.regex.Pattern;
* @Version: 1.0
*/
public class RestRemoteHandler implements InvocationHandler {
private static final Logger LOG = LoggerFactory.getLogger(RestRemoteHandler.class);
private static final Pattern PATH_VARIABLE = Pattern.compile("\\{[^\\s\\}]+\\}");
@Override
@ -41,34 +54,41 @@ public class RestRemoteHandler implements InvocationHandler {
* @return
*/
public Object handle(Method method, Object[] args) throws UnsupportedEncodingException {
if (method.getParameters().length == 0) {
throw new ParamsException("方法没有参数");
}
String remotePath = getRemotePath(method.getParameters(), args);
checkRemotePath(remotePath);
Map<String, String> pathVariableParams = getPathVariableParams(method.getParameters(), args);
Map<String, String> queryVariableParams = getQueryVariableParams(method.getParameters(), args);
Map<String, String> headerVariableParams = getHeaderVariableParams(method.getParameters(), args);
String uri;
Object requestBody = null;
RequestMethod requestMethod = null;
if (method.isAnnotationPresent(GetMapping.class)) {
RequestMethod requestMethod;
if (method.isAnnotationPresent(RemoteGetMethod.class)) {
// GET请求
requestMethod = RequestMethod.GET;
GetMapping getMapping = method.getAnnotation(GetMapping.class);
uri = getMapping.value()[0];
} else if (method.isAnnotationPresent(DeleteMapping.class)) {
RemoteGetMethod remoteGet = method.getAnnotation(RemoteGetMethod.class);
uri = remoteGet.value();
} else if (method.isAnnotationPresent(RemoteDeleteMethod.class)) {
// DELETE请求
requestMethod = RequestMethod.DELETE;
DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
uri = deleteMapping.value()[0];
} else if (method.isAnnotationPresent(PostMapping.class)) {
RemoteDeleteMethod deleteMethod = method.getAnnotation(RemoteDeleteMethod.class);
uri = deleteMethod.value();
} else if (method.isAnnotationPresent(RemotePostMethod.class)) {
// POST请求
requestMethod = RequestMethod.POST;
PostMapping postMapping = method.getAnnotation(PostMapping.class);
uri = postMapping.value()[0];
RemotePostMethod postMethod = method.getAnnotation(RemotePostMethod.class);
uri = postMethod.value();
requestBody = getRequestBody(method.getParameters(), args);
} else if (method.isAnnotationPresent(PutMapping.class)) {
checkJsonBody(requestBody);
} else if (method.isAnnotationPresent(RemotePutMethod.class)) {
// PUT请求
requestMethod = RequestMethod.PUT;
PutMapping putMapping = method.getAnnotation(PutMapping.class);
uri = putMapping.value()[0];
RemotePutMethod putMethod = method.getAnnotation(RemotePutMethod.class);
uri = putMethod.value();
requestBody = getRequestBody(method.getParameters(), args);
checkJsonBody(requestBody);
} else {
return null;
}
@ -76,13 +96,20 @@ public class RestRemoteHandler implements InvocationHandler {
checkPathVariables(pathVariable);
checkPathVariableParams(pathVariable, pathVariableParams);
uri = buildUri(uri, pathVariable, pathVariableParams);
uri = buildFullUri(uri, queryVariableParams);
String remoteFullPath = buildFullUri(remotePath, uri, queryVariableParams);
System.out.println("uri: " + uri);
// LOG.debug("remoteFullUri: {}", remoteFullUri);
// LOG.debug("requestBody: {}", requestBody);
// LOG.debug("headerVariableParams: {}", headerVariableParams);
// LOG.debug("requestMethod: {}", requestMethod.name());
System.out.println("remoteFullUri: " + remoteFullPath);
System.out.println("requestBody: " + requestBody);
System.out.println("headerVariableParams: " + headerVariableParams);
System.out.println("requestMethod: " + requestMethod.name());
return uri;
RestRemoteRequest restRemoteRequest = new RestRemoteRequest();
return restRemoteRequest.request(requestMethod, remoteFullPath, headerVariableParams, requestBody, method.getGenericReturnType());
}
/**
@ -111,10 +138,10 @@ public class RestRemoteHandler implements InvocationHandler {
Map<String, String> pathVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(PathVariable.class)) {
if (!parameter.isAnnotationPresent(RemotePathParams.class)) {
continue;
}
PathVariable annotation = parameter.getAnnotation(PathVariable.class);
RemotePathParams annotation = parameter.getAnnotation(RemotePathParams.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
@ -139,10 +166,10 @@ public class RestRemoteHandler implements InvocationHandler {
Map<String, String> queryVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RequestParam.class)) {
if (!parameter.isAnnotationPresent(RemoteQueryParams.class)) {
continue;
}
RequestParam annotation = parameter.getAnnotation(RequestParam.class);
RemoteQueryParams annotation = parameter.getAnnotation(RemoteQueryParams.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
@ -167,10 +194,10 @@ public class RestRemoteHandler implements InvocationHandler {
Map<String, String> headerVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RequestHeader.class)) {
if (!parameter.isAnnotationPresent(RemoteHeaderParams.class)) {
continue;
}
RequestHeader annotation = parameter.getAnnotation(RequestHeader.class);
RemoteHeaderParams annotation = parameter.getAnnotation(RemoteHeaderParams.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
@ -187,14 +214,17 @@ public class RestRemoteHandler implements InvocationHandler {
/**
* 获取请求体只取第一个
*
* @param parameters
* @param parameters 方法参数
* @param args
* @return
*/
private Object getRequestBody(Parameter[] parameters, Object[] args) {
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RequestBody.class)) {
if (!parameter.isAnnotationPresent(RemoteJsonBodyParams.class)) {
continue;
}
if (args[i] == null) {
continue;
}
return args[i];
@ -202,6 +232,26 @@ public class RestRemoteHandler implements InvocationHandler {
return null;
}
/**
* 获取远程地址只取第一个
*
* @param parameters 方法参数
* @param args 参数
* @return
*/
private String getRemotePath(Parameter[] parameters, Object[] args) {
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RemoteServer.class)) {
continue;
}
if (args[i] == null) {
continue;
}
return args[i].toString();
}
return null;
}
/**
* 检查路径变量
@ -247,12 +297,26 @@ public class RestRemoteHandler implements InvocationHandler {
*
* @param requestBody
*/
private void checkRequestBody(Object requestBody) {
private void checkJsonBody(Object requestBody) {
if (requestBody == null) {
throw new ParamsException("请求主体不能为空");
}
}
/**
* 校验远程请求路径
*
* @param remotePath
*/
private void checkRemotePath(String remotePath) {
if (StringUtils.isBlank(remotePath)) {
throw new ParamsException("远程请求路径不能为空");
}
if (!RegexUtil.isUrl(remotePath)) {
throw new ParamsException("远程请求路径格式错误");
}
}
/**
* 构建uri
*
@ -266,20 +330,22 @@ public class RestRemoteHandler implements InvocationHandler {
for (String pathVariable : pathVariables) {
resultUri = resultUri.replace("{" + pathVariable + "}", pathVariableParams.get(pathVariable));
}
return resultUri;
return resultUri.startsWith("/") ? resultUri : "/" + resultUri;
}
/**
* 构建完整路径
*
* @param uri
* @param queryVariableParams
* @param remotePath 远程调用地址
* @param uri 请求路径
* @param queryVariableParams 查询参数
* @return
* @throws UnsupportedEncodingException
*/
private String buildFullUri(String uri, Map<String, String> queryVariableParams) {
private String buildFullUri(String remotePath, String uri, Map<String, String> queryVariableParams) {
String remote = remotePath.endsWith("/") ? remotePath.substring(0, remotePath.length() - 1) : remotePath;
if (queryVariableParams.isEmpty()) {
return uri;
return remotePath + uri;
}
StringBuilder queryParams = new StringBuilder();
for (Map.Entry<String, String> kv : queryVariableParams.entrySet()) {
@ -288,7 +354,7 @@ public class RestRemoteHandler implements InvocationHandler {
}
queryParams.append(kv.getKey()).append("=").append(kv.getValue());
}
return uri + "?" + queryParams;
return remote + uri + "?" + queryParams;
}
}

View File

@ -1,10 +1,6 @@
package ink.wgink.util.remote.rest.proxy;
import ink.wgink.util.remote.rest.handler.RestRemoteHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import java.lang.reflect.Proxy;
@ -23,14 +19,4 @@ public class RestRemoteProxy {
return (T) o;
}
public interface IDemo {
@GetMapping("/demo/{p2}/{p1}")
String test(@PathVariable("p1") String p1, @PathVariable("p2") String p2, @RequestParam("q1") String q1, @RequestParam("q2") String q2, @RequestHeader("access_token") String token, @RequestHeader("auth") String auth);
}
public static void main(String[] args) {
IDemo instance = RestRemoteProxy.getInstance(IDemo.class);
instance.test("pp1", "我是", null, "中国人", "token123456", null);
}
}

View File

@ -1,5 +1,20 @@
package ink.wgink.util.remote.rest.request;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.remote.RemoteRequestException;
import ink.wgink.exceptions.remote.RemoteResponseException;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
@ -11,4 +26,166 @@ package ink.wgink.util.remote.rest.request;
* @Version: 1.0
**/
public class RestRemoteRequest {
private RestTemplate restTemplate;
public RestRemoteRequest() {
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpComponentsClientHttpRequestFactory.setConnectTimeout(20 * 1000);
httpComponentsClientHttpRequestFactory.setReadTimeout(60 * 1000);
this.restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory);
}
public Object request(RequestMethod requestMethod, String remoteUri, Map<String, String> headers, Object jsonBody, Type resultType) {
String result;
if (RequestMethod.GET.equals(requestMethod)) {
result = get(remoteUri, headers);
} else if (RequestMethod.DELETE.equals(requestMethod)) {
result = delete(remoteUri, headers);
} else if (RequestMethod.POST.equals(requestMethod)) {
result = post(remoteUri, headers, jsonBody);
} else if (RequestMethod.PUT.equals(requestMethod)) {
result = put(remoteUri, headers, jsonBody);
} else {
throw new ParamsException("请求方法不支持");
}
// 除了结合其余均按对象
return JSONObject.parseObject(result, resultType);
}
/**
* GET请求
*
* @param remoteUri
* @param headers
* @return
*/
public String get(String remoteUri, Map<String, String> headers) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null);
ResponseEntity<String> responseEntity = restTemplate.exchange(remoteUri, HttpMethod.GET, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof HttpClientErrorException) {
HttpClientErrorException exception = (HttpClientErrorException) e;
throw new RemoteResponseException(exception.getResponseBodyAsString());
}
throw new RemoteRequestException(e.getMessage(), e);
}
}
/**
* DELETE请求
*
* @param remoteUri
* @param headers
* @return
*/
public String delete(String remoteUri, Map<String, String> headers) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null);
ResponseEntity<String> responseEntity = restTemplate.exchange(remoteUri, HttpMethod.DELETE, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
if (e instanceof HttpClientErrorException) {
HttpClientErrorException exception = (HttpClientErrorException) e;
throw new RemoteResponseException(exception.getResponseBodyAsString());
}
throw new RemoteRequestException(e.getMessage(), e);
}
}
/**
* POST请求
*
* @param remoteUri
* @param headers
* @return
*/
public String post(String remoteUri, Map<String, String> headers, Object jsonBody) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, jsonBody);
ResponseEntity<String> responseEntity = restTemplate.exchange(remoteUri, HttpMethod.POST, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
if (e instanceof HttpClientErrorException) {
HttpClientErrorException exception = (HttpClientErrorException) e;
throw new RemoteResponseException(exception.getResponseBodyAsString());
}
throw new RemoteRequestException(e.getMessage(), e);
}
}
/**
* PUT请求
*
* @param remoteUri
* @param headers
* @return
*/
public String put(String remoteUri, Map<String, String> headers, Object jsonBody) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, jsonBody);
ResponseEntity<String> responseEntity = restTemplate.exchange(remoteUri, HttpMethod.PUT, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
if (e instanceof HttpClientErrorException) {
HttpClientErrorException exception = (HttpClientErrorException) e;
throw new RemoteResponseException(exception.getResponseBodyAsString());
}
throw new RemoteRequestException(e.getMessage(), e);
}
}
/**
* 请求实体
*
* @param headerMap
* @param jsonBody
* @return
*/
private HttpEntity<String> getHttpEntity(Map<String, String> headerMap, Object jsonBody) {
HttpEntity<String> httpEntity;
if (jsonBody != null) {
if (jsonBody instanceof Collection) {
httpEntity = new HttpEntity(JSONArray.toJSONString(jsonBody), getHttpHeaders(headerMap));
} else {
httpEntity = new HttpEntity(JSONObject.toJSONString(jsonBody), getHttpHeaders(headerMap));
}
} else {
httpEntity = new HttpEntity(getHttpHeaders(headerMap));
}
return httpEntity;
}
/**
* 得到HTTP请求头
*
* @param headersMap
* @return
*/
private HttpHeaders getHttpHeaders(Map<String, String> headersMap) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Accept", MediaType.APPLICATION_JSON_VALUE);
httpHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
for (Map.Entry<String, String> kv : headersMap.entrySet()) {
httpHeaders.add(kv.getKey(), kv.getValue());
}
return httpHeaders;
}
/**
* 得到响应结果
*
* @param responseEntity
* @return
*/
private String getStringResponse(ResponseEntity<String> responseEntity) {
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RemoteResponseException("远程调用响应状态码不支持: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
}

View File

@ -0,0 +1,88 @@
import ink.wgink.annotation.remote.RemoteServer;
import ink.wgink.annotation.remote.method.RemoteDeleteMethod;
import ink.wgink.annotation.remote.method.RemoteGetMethod;
import ink.wgink.annotation.remote.method.RemotePostMethod;
import ink.wgink.annotation.remote.method.RemotePutMethod;
import ink.wgink.annotation.remote.params.RemoteJsonBodyParams;
import ink.wgink.annotation.remote.params.RemotePathParams;
import ink.wgink.annotation.remote.params.RemoteQueryParams;
import ink.wgink.pojo.dtos.user.UserDTO;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.remote.rest.proxy.RestRemoteProxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName: RemoteTest
* @Description: 远程调用
* @Author: wanggeng
* @Date: 2021/9/19 11:28 下午
* @Version: 1.0
*/
public class RemoteTest {
public interface IDemo {
@RemoteGetMethod("/app/user-expand/get-user-release/{userId}")
UserDTO getUser(@RemoteServer String remotePath, @RemotePathParams("userId") String userId);
@RemoteGetMethod("/app/user-expand/list-user-release")
List<UserDTO> listUser(@RemoteServer String remotePath);
@RemoteGetMethod("/app/user-expand/listpage-user-release")
SuccessResultList<List<UserDTO>> listPageUser(@RemoteServer String remotePath, @RemoteQueryParams("page") Integer page, @RemoteQueryParams("size") Integer size);
@RemotePostMethod("/app/user-expand/save-release")
SuccessResult postRelease(@RemoteServer String remotePath, @RemoteJsonBodyParams Map<String, Object> params);
@RemotePostMethod("/app/user-expand/save-list-release")
SuccessResult postListRelease(@RemoteServer String remotePath, @RemoteJsonBodyParams List<Map<String, Object>> params);
@RemotePutMethod("/app/user-expand/update-release")
SuccessResult putRelease(@RemoteServer String remotePath, @RemoteJsonBodyParams Map<String, Object> params);
@RemoteDeleteMethod("/app/user-expand/delete-release/{userIds}")
SuccessResult deleteRelease(@RemoteServer String remotePath, @RemotePathParams("userIds") String userIds);
}
public static void main(String[] args) {
String remotePath = "http://127.0.0.1:7008/study";
IDemo instance = RestRemoteProxy.getInstance(IDemo.class);
UserDTO userDTO = instance.getUser(remotePath, "e48e9c4a-995e-4061-abcd-a3c260c11333");
System.out.println(userDTO);
System.out.println();
List<UserDTO> userDTOs = instance.listUser(remotePath);
System.out.println(userDTOs.size());
System.out.println();
SuccessResultList<List<UserDTO>> successResultUserList = instance.listPageUser(remotePath, 1, 5);
System.out.println(successResultUserList.getPage());
System.out.println();
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("aaa", "aaa1");
SuccessResult successResult = instance.postRelease(remotePath, requestBody);
System.out.println(successResult);
System.out.println();
List<Map<String, Object>> listBody = new ArrayList<>();
listBody.add(requestBody);
SuccessResult successResult1 = instance.postListRelease(remotePath, listBody);
System.out.println(successResult1);
System.out.println();
requestBody.put("aaa", "aaa2");
SuccessResult successResult2 = instance.putRelease(remotePath, requestBody);
System.out.println(successResult2);
System.out.println();
SuccessResult successResult3 = instance.deleteRelease(remotePath, "abc_def_ghi");
System.out.println(successResult3);
System.out.println();
}
}