完善Rest远程调用类功能
This commit is contained in:
parent
8f23bca7e2
commit
f2ff322147
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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