完善Rest远程调用类功能
This commit is contained in:
parent
8f23bca7e2
commit
f2ff322147
@ -1,7 +1,21 @@
|
|||||||
package ink.wgink.util.remote.rest.handler;
|
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.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
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
|
* @ClassName: RestRemoterHandler
|
||||||
@ -12,15 +26,269 @@ import java.lang.reflect.Method;
|
|||||||
*/
|
*/
|
||||||
public class RestRemoteHandler implements InvocationHandler {
|
public class RestRemoteHandler implements InvocationHandler {
|
||||||
|
|
||||||
|
private static final Pattern PATH_VARIABLE = Pattern.compile("\\{[^\\s\\}]+\\}");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
System.out.println(method.getDeclaringClass().getClassLoader());
|
return handle(method, args);
|
||||||
// 否则执行统一接口处理方法
|
|
||||||
return method.invoke(this, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package ink.wgink.util.remote.rest.proxy;
|
package ink.wgink.util.remote.rest.proxy;
|
||||||
|
|
||||||
import ink.wgink.util.remote.rest.handler.RestRemoteHandler;
|
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;
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
@ -20,19 +24,13 @@ public class RestRemoteProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface IDemo {
|
public interface IDemo {
|
||||||
String say();
|
@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 class DemoImpl implements IDemo {
|
|
||||||
@Override
|
|
||||||
public String say() {
|
|
||||||
return "go";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
IDemo demo = RestRemoteProxy.getInstance(IDemo.class);
|
IDemo instance = RestRemoteProxy.getInstance(IDemo.class);
|
||||||
System.out.println(demo.say());
|
instance.test("pp1", "我是", null, "中国人", "token123456", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user