Skip to content

Commit daceb0e

Browse files
committed
⚡ use trie mapping replace regex mapping
1 parent a0abf0d commit daceb0e

File tree

6 files changed

+61
-153
lines changed

6 files changed

+61
-153
lines changed

blade-core/src/main/java/com/hellokaton/blade/mvc/route/Route.java

Lines changed: 17 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import com.hellokaton.blade.mvc.ui.ResponseType;
66
import lombok.AllArgsConstructor;
77
import lombok.Builder;
8-
import lombok.EqualsAndHashCode;
8+
import lombok.Data;
99

1010
import java.lang.reflect.Method;
11-
import java.util.HashMap;
11+
import java.util.Collections;
1212
import java.util.Map;
1313

1414
/**
@@ -19,11 +19,11 @@
1919
* the Http method, and the method of executing the route
2020
*
2121
* @author <a href="mailto:hellokaton@gmail.com" target="_blank">hellokaton</a>
22-
* @since 1.5
22+
* @since 2.1.2.RELEASE
2323
*/
24+
@Data
2425
@Builder
2526
@AllArgsConstructor
26-
@EqualsAndHashCode
2727
public class Route {
2828

2929
/**
@@ -36,6 +36,8 @@ public class Route {
3636
*/
3737
private String path;
3838

39+
private String rewritePath;
40+
3941
/**
4042
* Logical controller object
4143
*/
@@ -61,16 +63,18 @@ public class Route {
6163
* Url path params
6264
*/
6365
@Builder.Default
64-
private Map<String, String> pathParams = new HashMap<>(2);
66+
private Map<String, String> pathParams = Collections.emptyMap();
6567

6668
public Route() {
6769
this.sort = Integer.MAX_VALUE;
6870
}
6971

7072
public Route(HttpMethod httpMethod, String path, Class<?> targetType, Method action) {
71-
super();
7273
this.httpMethod = httpMethod;
7374
this.path = PathKit.fixPath(path);
75+
if (this.path.contains("*")) {
76+
this.rewritePath = this.path.replaceAll("\\*", "");
77+
}
7478
this.targetType = targetType;
7579
this.action = action;
7680
this.sort = Integer.MAX_VALUE;
@@ -81,6 +85,9 @@ public Route(HttpMethod httpMethod, String path, Object target,
8185
super();
8286
this.httpMethod = httpMethod;
8387
this.path = PathKit.fixPath(path);
88+
if (this.path.contains("*")) {
89+
this.rewritePath = this.path.replaceAll("\\*", "");
90+
}
8491
this.target = target;
8592
this.targetType = targetType;
8693
this.action = action;
@@ -91,124 +98,21 @@ public Route(HttpMethod httpMethod, String path, Object target,
9198
public Route(Route route) {
9299
this.httpMethod = route.httpMethod;
93100
this.path = route.path;
101+
if (this.path.contains("*")) {
102+
this.rewritePath = this.path.replaceAll("\\*", "");
103+
}
94104
this.target = route.target;
95105
this.targetType = route.targetType;
96106
this.action = route.action;
107+
this.isWildcard = route.isWildcard;
97108
this.responseType = route.responseType;
98109
this.sort = route.sort;
99110
}
100111

101-
/**
102-
* Return http method
103-
*
104-
* @return HttpMethod
105-
*/
106-
public HttpMethod getHttpMethod() {
107-
return httpMethod;
108-
}
109-
110-
/**
111-
* Return route path
112-
*
113-
* @return path string
114-
*/
115-
public String getPath() {
116-
return path;
117-
}
118-
119-
/**
120-
* Set route path
121-
*
122-
* @param path string path
123-
*/
124-
public void setPath(String path) {
125-
this.path = path;
126-
}
127-
128-
/**
129-
* Return route controller instance
130-
*
131-
* @return route handler instance
132-
*/
133-
public Object getTarget() {
134-
return target;
135-
}
136-
137-
/**
138-
* Set route handler instance
139-
*
140-
* @param target target bean
141-
*/
142-
public void setTarget(Object target) {
143-
this.target = target;
144-
}
145-
146-
public void setWildcard(boolean wildcard) {
147-
this.isWildcard = wildcard;
148-
}
149-
150-
/**
151-
* Return route method
152-
*
153-
* @return route Method
154-
*/
155-
public Method getAction() {
156-
return action;
157-
}
158-
159-
/**
160-
* Get route handler type
161-
*
162-
* @return return target type
163-
*/
164-
public Class<?> getTargetType() {
165-
return targetType;
166-
}
167-
168-
/**
169-
* Get route path parameters
170-
*
171-
* @return return path params
172-
*/
173-
public Map<String, String> getPathParams() {
174-
return this.pathParams;
175-
}
176-
177-
/**
178-
* Set path params
179-
*
180-
* @param pathParams path params map
181-
*/
182-
public void setPathParams(Map<String, String> pathParams) {
183-
this.pathParams = pathParams;
184-
}
185-
186-
/**
187-
* Get route execution sort, default is Integer.MAX_VALUE
188-
*
189-
* @return return sort
190-
*/
191-
public int getSort() {
192-
return sort;
193-
}
194-
195-
/**
196-
* Set route execution sort
197-
*
198-
* @param sort sort number
199-
*/
200-
public void setSort(int sort) {
201-
this.sort = sort;
202-
}
203-
204112
public String getAllPath() {
205113
return this.path + "#" + this.httpMethod.name();
206114
}
207115

208-
public ResponseType getResponseType() {
209-
return this.responseType;
210-
}
211-
212116
/**
213117
* Route to string
214118
*

blade-core/src/main/java/com/hellokaton/blade/mvc/route/RouteBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private void parseRoute(RouteStruct routeStruct) {
9898
for (String path : paths) {
9999
String pathV = getRoutePath(path, routeStruct.nameSpace, routeStruct.suffix);
100100

101-
routeMatcher.addRoute(com.hellokaton.blade.mvc.route.Route.builder()
101+
routeMatcher.addRoute(Route.builder()
102102
.target(routeStruct.controller)
103103
.targetType(routeStruct.routeType)
104104
.action(routeStruct.method)

blade-core/src/main/java/com/hellokaton/blade/mvc/route/RouteMatcher.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ private Route addRoute(HttpMethod httpMethod, String path, Object controller,
7474
if (null != order) {
7575
route.setSort(order.value());
7676
}
77-
if (route.getPath().contains("*")) {
78-
route.setPath(route.getPath().replaceAll("\\*", ""));
79-
}
8077
if (this.hooks.containsKey(key)) {
8178
this.hooks.get(key).add(route);
8279
} else {
@@ -121,7 +118,7 @@ public void route(String path, Class<?> clazz, String methodName, HttpMethod htt
121118
for (Method method : methods) {
122119
if (method.getName().equals(methodName)) {
123120
Object controller = controllerPool.computeIfAbsent(clazz, k -> ReflectKit.newInstance(clazz));
124-
addRoute(httpMethod, path, controller, clazz, method, null);
121+
this.addRoute(httpMethod, path, controller, clazz, method, null);
125122
}
126123
}
127124
} catch (Exception e) {
@@ -161,7 +158,8 @@ public List<Route> getBefore(String path) {
161158
List<Route> collect = hooks.values().stream()
162159
.flatMap(Collection::stream)
163160
.sorted(Comparator.comparingInt(Route::getSort))
164-
.filter(route -> route.getHttpMethod() == HttpMethod.BEFORE && matchesPath(route.getPath(), cleanPath))
161+
.filter(route -> route.getHttpMethod() == HttpMethod.BEFORE)
162+
.filter(route -> matchesPath(route.getPath(), cleanPath))
165163
.collect(Collectors.toList());
166164

167165
this.giveMatch(path, collect);
@@ -179,7 +177,8 @@ public List<Route> getAfter(String path) {
179177
List<Route> afters = hooks.values().stream()
180178
.flatMap(Collection::stream)
181179
.sorted(Comparator.comparingInt(Route::getSort))
182-
.filter(route -> route.getHttpMethod() == HttpMethod.AFTER && matchesPath(route.getPath(), cleanPath))
180+
.filter(route -> route.getHttpMethod() == HttpMethod.AFTER)
181+
.filter(route -> matchesPath(route.getPath(), cleanPath))
183182
.collect(Collectors.toList());
184183

185184
this.giveMatch(path, afters);
@@ -220,9 +219,6 @@ private void giveMatch(final String uri, List<Route> routes) {
220219
* @return return match is success
221220
*/
222221
private boolean matchesPath(String routePath, String pathToMatch) {
223-
if ("/".equals(routePath)) {
224-
return true;
225-
}
226222
return pathToMatch.startsWith(routePath);
227223
}
228224

blade-core/src/main/java/com/hellokaton/blade/mvc/route/mapping/dynamic/TrieMapping.java

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212

1313
/**
1414
* Trie tree based url route
15-
*
15+
* <p>
1616
* Support:
17-
* - * : match any one part
18-
* - /* : match suffix with any number of parts
19-
* - :xxx : match one part as path variable
20-
*
17+
* - * : match any one part
18+
* - /* : match suffix with any number of parts
19+
* - :xxx : match one part as path variable
20+
* <p>
2121
* Example:
22-
* - /aaa/* : /aaa/bbb, /aaa/bbb/ccc
23-
* - /aaa/*\/ccc : /aaa/bbb/ccc, /aaa/ddd/ccc
24-
* - /aaa/*\/ccc/*
25-
* - /aaa/bbb/:id : /aaa/bbb/ccc
26-
* - /aaa/bbb/:name/:id
22+
* - /aaa/* : /aaa/bbb, /aaa/bbb/ccc
23+
* - /aaa/*\/ccc : /aaa/bbb/ccc, /aaa/ddd/ccc
24+
* - /aaa/*\/ccc/*
25+
* - /aaa/bbb/:id : /aaa/bbb/ccc
26+
* - /aaa/bbb/:name/:id
2727
*
2828
* @author: dqyuan
2929
* @date: 2020/06/25
@@ -107,15 +107,16 @@ public Node putChildIfAbsent(Node child, boolean isEnd) {
107107
return staticChildren.computeIfAbsent(child.getPart(), ignore -> child);
108108
}
109109
throw new IllegalStateException(
110-
String.format("%s conflict with path %s", child.getPart(),
111-
dynamicChild.getPart())
110+
String.format("%s conflict with path %s", child.getPart(),
111+
dynamicChild.getPart())
112112
);
113113
}
114114
throw new IllegalStateException();
115115
}
116116

117117
/**
118118
* is end of a url
119+
*
119120
* @return
120121
*/
121122
public boolean isEnd() {
@@ -147,19 +148,14 @@ public void addRoute(HttpMethod httpMethod, Route route, List<String> uriVariabl
147148

148149
Node prev = root;
149150

150-
if ("/".equals(route.getPath())) {
151-
Node nodeByPart = getNodeByPart(path);
152-
if (NodeType.WILD.equals(nodeByPart.type)) {
153-
route.setWildcard(true);
154-
}
155-
prev = prev.putChildIfAbsent(nodeByPart, true);
156-
prev.getRouteMap().put(httpMethod, route);
157-
return;
151+
String[] parts;
152+
if ("/".equals(path)) {
153+
parts = new String[]{"/"};
154+
} else {
155+
path = StringKit.strip(path, "/");
156+
parts = path.split("/");
158157
}
159158

160-
path = StringKit.strip(route.getPath(), "/");
161-
162-
String[] parts = path.split("/");
163159
for (int i = 0; i < parts.length; i++) {
164160
String part = parts[i];
165161
if (StringKit.isBlank(part)) {
@@ -201,7 +197,7 @@ public void register() {
201197
@Override
202198
public Route findRoute(String httpMethod, String path) {
203199
HttpMethod requestMethod = HttpMethod.valueOf(httpMethod);
204-
Map<String, String> uriVariables = new LinkedHashMap<>(2);
200+
Map<String, String> uriVariables = null;
205201
Iterator<String> partIter = partIter(path);
206202
Node prev = root;
207203
walk:
@@ -227,6 +223,9 @@ public Route findRoute(String httpMethod, String path) {
227223
}
228224
prev = prev.getDynamicChild();
229225
if (prev.getType() == NodeType.PARAM) {
226+
if (null == uriVariables) {
227+
uriVariables = new LinkedHashMap<>(2);
228+
}
230229
uriVariables.put(prev.getPart().substring(1), part);
231230
}
232231
break;
@@ -243,7 +242,9 @@ public Route findRoute(String httpMethod, String path) {
243242
return null;
244243
}
245244
Route route = new Route(selectedRoute);
246-
route.setPathParams(uriVariables);
245+
if (null != uriVariables) {
246+
route.setPathParams(uriVariables);
247+
}
247248
return route;
248249
}
249250

@@ -257,6 +258,11 @@ protected Iterator<String> partIter(String path) {
257258

258259
@Override
259260
public boolean hasNext() {
261+
if (this.start == 1 && "/".equals(path)) {
262+
// return true;
263+
this.start = 0;
264+
this.end = 1;
265+
}
260266
return end <= path.length();
261267
}
262268

blade-core/src/main/java/com/hellokaton/blade/server/StaticFileHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,12 @@ public void handle(WebContext webContext) throws Exception {
105105

106106
Instant start = Instant.now();
107107

108-
Route route = webContext.getRoute();
109-
110108
String uri = request.attribute(REQUEST_TO_STATIC_ATTR);
111109
if (null != uri) {
112-
110+
Route route = webContext.getRoute();
111+
if (route.isWildcard()) {
112+
uri = uri + request.uri().replace(route.getRewritePath(), "");
113+
}
113114
} else {
114115
uri = URLDecoder.decode(request.uri(), "UTF-8");
115116
}
@@ -314,7 +315,7 @@ private File getGradleResourcesDirectory() {
314315
private String getCleanURL(Request request, String uri) {
315316
uri = PathKit.cleanPath(uri.replaceFirst(request.contextPath(), "/"));
316317
if (uri.endsWith("/")) {
317-
uri = uri.substring(0, uri.length() - 1);
318+
uri = StringKit.stripEnd(uri, "/");
318319
}
319320
return uri;
320321
}

0 commit comments

Comments
 (0)