1821349743@qq.com
2023-02-20 b83f9e66707ee3431551909acffab7b405b94bad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
package com.product.module.data.utli;
 
import com.product.core.exception.BaseException;
import com.product.module.data.config.CmnCode;
import com.product.module.sys.version.ApiVersion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
 
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 * cheng
 */
@Component
public class SystemApiToMethods {
    @Autowired
    ConfigurableApplicationContext applicationContext;
    /**
     * 只读map
     */
    Map<String, Bean> beans;
 
 
    public Boolean getBeanIsExist(String api) {
        Bean bean = this.beans.get(api);
        return bean != null;
    }
 
    /**
     * 通过api调用Controller层入口
     *
     * @param api
     * @return
     * @throws BaseException
     */
    public Object run(String api, Integer verion) throws BaseException {
        if (api == null) {
            return null;
        }
        if (api.indexOf("/") != 0) {
            api = "/" + api;
        }
        //通过上下文获取 request response
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        return run(request, response, api, verion);
    }
 
    public boolean isVersion(String api) {
        String str = api;
        String pattern = ".*/v[0-9]*\\d$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(str);
        return m.matches();
    }
 
 
    public static void main(String args[]) {
 
    }
 
    /**
     * 通过api调用Controller层入口
     *
     * @param request
     * @param response
     * @param api
     * @return
     * @throws BaseException
     */
    public Object run(HttpServletRequest request, HttpServletResponse response, String api, Integer version) throws BaseException {
        if (beans == null || api == null) return null;
        try {
            if (api.indexOf("/") != 0) {
                api = "/" + api;
            }
            api += version == null ? "" : !isVersion(api) ? "/v" + version : "";
            if (!getBeanIsExist(api)) {
                throw new BaseException(CmnCode.EXPORT_GET_API_METHOD_FILA.getValue(), CmnCode.EXPORT_GET_API_METHOD_FILA.getText() + api);
            }
            Bean bean = this.beans.get(api);
            if (bean != null) {
                Class<?>[] parameterType = bean.getParameterType();
                if (parameterType != null) {
                    Object[] params = new Object[parameterType.length];
                    for (int i = 0; i < parameterType.length; i++) {
                        Class<?> aClass = parameterType[i];
                        Class<?> httpServletRequestClass = HttpServletRequest.class;
                        Class<?> HttpServletResponseClass = HttpServletResponse.class;
                        if (aClass == httpServletRequestClass) {
                            params[i] = request;
                            continue;
                        }
                        if (aClass == HttpServletResponseClass) {
                            params[i] = response;
                            continue;
                        }
                        params[i] = null;
                    }
                    return bean.method.invoke(bean.bean, params);
                }
                return bean.method.invoke(bean.bean);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(e);
        }
    }
 
    /**
     * 启动时初始化拿到所有的请求地址
     */
    @PostConstruct
    private void getAll() {
 
        //获取restcontroller注解的类名
        String[] beanNamesForAnnotation = applicationContext.getBeanNamesForAnnotation(RestController.class);
        Map<String, Bean> beanMap = new HashMap<>();
        //获取类对象
        for (String str : beanNamesForAnnotation) {
            Object bean = applicationContext.getBean(str);
            Class<?> forName = bean.getClass();
            //获取requestmapping注解的类
            RequestMapping declaredAnnotation = forName.getAnnotation(RequestMapping.class);
            if (declaredAnnotation != null) {
                String[] value = (declaredAnnotation.value());
                for (Method method : forName.getDeclaredMethods()) {
                    ApiVersion version = method.getAnnotation(ApiVersion.class);
                    RequestMapping api_value = method.getAnnotation(RequestMapping.class);
                    PostMapping annotation = method.getAnnotation(PostMapping.class);
                    if (api_value != null) {
                        Bean bean1 = new Bean();
                        String class_url = value[0] + api_value.value()[0].replace("{version}", "v" + (version == null ? "1" : String.valueOf(version.value())));
                        bean1.apiUrl = class_url;
                        bean1.version = version == null ? 1 : version.value();
                        bean1.bean = bean;
                        bean1.method = method;
                        beanMap.put(class_url, bean1);
                    } else if (annotation != null) {
                        Bean bean1 = new Bean();
                        String class_url = value[0] + annotation.value()[0].replace("{version}", "v" + (version == null ? "1" : "" + version.value()));
                        bean1.apiUrl = class_url;
                        bean1.version = version == null ? 1 : version.value();
                        bean1.bean = bean;
                        bean1.method = method;
                        beanMap.put(class_url, bean1);
                    }
                }
            }
            PostMapping annotation = forName.getAnnotation(PostMapping.class);
            if (annotation != null) {
                String[] value = annotation.value();
                for (Method method : forName.getDeclaredMethods()) {
                    ApiVersion version = method.getAnnotation(ApiVersion.class);
                    PostMapping api_value = method.getAnnotation(PostMapping.class);
                    if (api_value != null) {
                        Bean bean1 = new Bean();
                        String class_url = value[0] + api_value.value()[0].replace("{version}", "v" + (version == null ? "1" : "" + version.value()));
                        bean1.apiUrl = class_url;
                        bean1.version = version == null ? 1 : version.value();
                        bean1.bean = bean;
                        bean1.method = method;
                        beanMap.put(class_url, bean1);
                    }
                }
            }
        }
        this.beans = Collections.unmodifiableMap(beanMap);
    }
 
    private class Bean implements Serializable {
 
 
        private String apiUrl;
 
        private int version;
 
        private Object bean;
 
        private Method method;
 
        private ParameterizedType parameterizedType;
 
        public Method getMethod() {
            return method;
        }
 
        public void setMethod(Method method) {
            this.method = method;
        }
 
        public String getApiUrl() {
            return apiUrl;
        }
 
        public void setApiUrl(String apiUrl) {
            this.apiUrl = apiUrl;
        }
 
        public int getVersion() {
            return version;
        }
 
        public void setVersion(int version) {
            this.version = version;
        }
 
        public Object getBean() {
            return bean;
        }
 
        public void setBean(Object bean) {
            this.bean = bean;
        }
 
        private Class<?>[] getParameterType() {
            if (this.bean != null && this.method != null) {
                return this.method.getParameterTypes();
            }
            return null;
        }
 
 
    }
 
}