完善Rest远程调用类功能

This commit is contained in:
WenG 2021-09-19 00:33:31 +08:00
parent 8f23bca7e2
commit f2ff322147
3 changed files with 295 additions and 15 deletions

View File

@ -1,7 +1,21 @@
package ink.wgink.util.remote.rest.handler;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.base.SystemException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @ClassName: RestRemoterHandler
@ -12,15 +26,269 @@ import java.lang.reflect.Method;
*/
public class RestRemoteHandler implements InvocationHandler {
private static final Pattern PATH_VARIABLE = Pattern.compile("\\{[^\\s\\}]+\\}");
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getDeclaringClass().getClassLoader());
// 否则执行统一接口处理方法
return method.invoke(this, args);
return handle(method, args);
}
public Object run() {
return "run";
/**
* 处理
*
* @param method
* @param args
* @return
*/
public Object handle(Method method, Object[] args) throws UnsupportedEncodingException {
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)) {
// GET请求
requestMethod = RequestMethod.GET;
GetMapping getMapping = method.getAnnotation(GetMapping.class);
uri = getMapping.value()[0];
} else if (method.isAnnotationPresent(DeleteMapping.class)) {
// DELETE请求
requestMethod = RequestMethod.DELETE;
DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
uri = deleteMapping.value()[0];
} else if (method.isAnnotationPresent(PostMapping.class)) {
// POST请求
requestMethod = RequestMethod.POST;
PostMapping postMapping = method.getAnnotation(PostMapping.class);
uri = postMapping.value()[0];
requestBody = getRequestBody(method.getParameters(), args);
} else if (method.isAnnotationPresent(PutMapping.class)) {
// PUT请求
requestMethod = RequestMethod.PUT;
PutMapping putMapping = method.getAnnotation(PutMapping.class);
uri = putMapping.value()[0];
requestBody = getRequestBody(method.getParameters(), args);
} else {
return null;
}
List<String> pathVariable = listPathVariables(uri);
checkPathVariables(pathVariable);
checkPathVariableParams(pathVariable, pathVariableParams);
uri = buildUri(uri, pathVariable, pathVariableParams);
uri = buildFullUri(uri, queryVariableParams);
System.out.println("uri: " + uri);
System.out.println("requestBody: " + requestBody);
System.out.println("headerVariableParams: " + headerVariableParams);
System.out.println("requestMethod: " + requestMethod.name());
return uri;
}
/**
* 路径变量列表
*
* @param uri 路径
* @return
*/
private List<String> listPathVariables(String uri) {
List<String> pathVariables = new ArrayList<>();
Matcher matcher = PATH_VARIABLE.matcher(uri);
while (matcher.find()) {
String variable = matcher.group();
pathVariables.add(variable.substring(1, variable.length() - 1));
}
return pathVariables;
}
/**
* 路径参数
*
* @param parameters
* @return
*/
private Map<String, String> getPathVariableParams(Parameter[] parameters, Object[] args) throws UnsupportedEncodingException {
Map<String, String> pathVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(PathVariable.class)) {
continue;
}
PathVariable annotation = parameter.getAnnotation(PathVariable.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
}
Object arg = args[i];
if (arg == null) {
throw new SystemException("路径参数不能为空: " + variableName);
}
pathVariableParamsMap.put(variableName, URLEncoder.encode(arg.toString(), "UTF-8"));
}
return pathVariableParamsMap;
}
/**
* 请求参数
*
* @param parameters
* @param args
* @return
*/
private Map<String, String> getQueryVariableParams(Parameter[] parameters, Object[] args) throws UnsupportedEncodingException {
Map<String, String> queryVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RequestParam.class)) {
continue;
}
RequestParam annotation = parameter.getAnnotation(RequestParam.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
}
Object arg = args[i];
if (arg == null) {
continue;
}
queryVariableParamsMap.put(variableName, URLEncoder.encode(arg.toString(), "UTF-8"));
}
return queryVariableParamsMap;
}
/**
* 请求头
*
* @param parameters
* @param args
* @return
*/
private Map<String, String> getHeaderVariableParams(Parameter[] parameters, Object[] args) throws UnsupportedEncodingException {
Map<String, String> headerVariableParamsMap = new HashMap<>();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RequestHeader.class)) {
continue;
}
RequestHeader annotation = parameter.getAnnotation(RequestHeader.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
}
Object arg = args[i];
if (arg == null) {
continue;
}
headerVariableParamsMap.put(variableName, URLEncoder.encode(arg.toString(), "UTF-8"));
}
return headerVariableParamsMap;
}
/**
* 获取请求体只取第一个
*
* @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)) {
continue;
}
return args[i];
}
return null;
}
/**
* 检查路径变量
*
* @param pathVariables 路劲变量列表
*/
private void checkPathVariables(List<String> pathVariables) {
for (int i = 0; i < pathVariables.size() - 1; i++) {
for (int j = i + 1; j < pathVariables.size(); j++) {
if (StringUtils.equals(pathVariables.get(i), pathVariables.get(j))) {
throw new ParamsException("路径变量 " + pathVariables.get(i) + "[" + i + "] 与 " + pathVariables.get(j) + "[" + j + "] 重复");
}
}
}
}
/**
* 检查路径变量与参数
*
* @param pathVariables 路劲变量列表
* @param pathVariableParams 路径参数Map
*/
private void checkPathVariableParams(List<String> pathVariables, Map<String, String> pathVariableParams) {
if (pathVariables.size() != pathVariableParams.size()) {
throw new SystemException("路径变量与参数数量不一致");
}
for (String pathVariable : pathVariables) {
boolean isExist = false;
for (Map.Entry<String, String> kv : pathVariableParams.entrySet()) {
if (StringUtils.equals(pathVariable, kv.getKey())) {
isExist = true;
break;
}
}
if (!isExist) {
throw new ParamsException("路径变量" + pathVariable + " 不存在参数");
}
}
}
/**
* 校验请求主体
*
* @param requestBody
*/
private void checkRequestBody(Object requestBody) {
if (requestBody == null) {
throw new ParamsException("请求主体不能为空");
}
}
/**
* 构建uri
*
* @param uri
* @param pathVariables
* @param pathVariableParams
* @return
*/
private String buildUri(String uri, List<String> pathVariables, Map<String, String> pathVariableParams) {
String resultUri = uri;
for (String pathVariable : pathVariables) {
resultUri = resultUri.replace("{" + pathVariable + "}", pathVariableParams.get(pathVariable));
}
return resultUri;
}
/**
* 构建完整路径
*
* @param uri
* @param queryVariableParams
* @return
* @throws UnsupportedEncodingException
*/
private String buildFullUri(String uri, Map<String, String> queryVariableParams) {
if (queryVariableParams.isEmpty()) {
return uri;
}
StringBuilder queryParams = new StringBuilder();
for (Map.Entry<String, String> kv : queryVariableParams.entrySet()) {
if (queryParams.length() > 0) {
queryParams.append("&");
}
queryParams.append(kv.getKey()).append("=").append(kv.getValue());
}
return uri + "?" + queryParams;
}
}

View File

@ -1,6 +1,10 @@
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;
@ -20,19 +24,13 @@ public class RestRemoteProxy {
}
public interface IDemo {
String say();
}
public static class DemoImpl implements IDemo {
@Override
public String say() {
return "go";
}
@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 demo = RestRemoteProxy.getInstance(IDemo.class);
System.out.println(demo.say());
IDemo instance = RestRemoteProxy.getInstance(IDemo.class);
instance.test("pp1", "我是", null, "中国人", "token123456", null);
}
}

View File

@ -0,0 +1,14 @@
package ink.wgink.util.remote.rest.request;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
*
* @ClassName: RestRemoteRequest
* @Description: Rest远程调用请求
* @Author: WangGeng
* @Date: 2021/9/18 21:00
* @Version: 1.0
**/
public class RestRemoteRequest {
}