2
2
3
3
import io .vertx .core .AbstractVerticle ;
4
4
import io .vertx .core .Future ;
5
+ import io .vertx .core .eventbus .ReplyException ;
6
+ import io .vertx .core .eventbus .ReplyFailure ;
5
7
import io .vertx .core .http .HttpServerResponse ;
6
8
import io .vertx .core .json .JsonArray ;
7
9
import io .vertx .core .json .JsonObject ;
14
16
import org .apache .logging .log4j .Logger ;
15
17
16
18
import java .util .Arrays ;
17
- import java .util .regex .Matcher ;
18
- import java .util .regex .Pattern ;
19
+ import java .util .stream .Collectors ;
19
20
20
21
public class ApiVerticle extends AbstractVerticle {
21
- private Logger log = LogManager .getLogger (this .getClass ());
22
+ // private Logger log = LogManager.getLogger(this.getClass());
22
23
23
24
@ Override
24
25
public void start (Future <Void > startFuture ) {
25
26
Router router = Router .router (vertx );
26
27
router .route ().handler (BodyHandler .create ());
27
28
router .get ("/*" ).handler (this ::log ); // 全局日志处理,会执行 next() 到下一个
28
29
router .get ("/" ).handler (this ::handleRoot ); // 首页
29
- router .get ("/favicon.ico" ).handler (c -> returnError ( c , new Exception ( " 404" ) )); // 针对浏览器返回404
30
+ router .get ("/favicon.ico" ).handler (c -> c . fail ( 404 )); // 针对浏览器返回404
30
31
router .get ("/log" ).handler (this ::showLog ); // 显示日志
31
- router .get ("/*" ). handler ( this :: handleGushici ); // 核心API调用
32
- router . route (). last (). handler (c -> { // 其他返回 404 (应该不会走到这里)
33
- returnError ( c , new Exception ( " 404" ));
34
- });
32
+ router .routeWithRegex ("/([a-z0-9/]*) \\ .?(txt|json|png|svg|)" )
33
+ . handler (this :: handleGushici ); // 核心API调用
34
+ router . route (). last (). handler ( c -> c . fail ( 404 )) // 其他返回404
35
+ . failureHandler ( this :: returnError ); // 对上面所有的错误进行处理
35
36
vertx
36
37
.createHttpServer ()
37
38
.requestHandler (router ::accept )
@@ -58,25 +59,25 @@ private void handleRoot(RoutingContext routingContext) {
58
59
result .put ("list" , res .result ().body ());
59
60
returnJsonWithCache (routingContext , result );
60
61
} else {
61
- returnError ( routingContext , res .cause ());
62
+ routingContext . fail ( res .cause ());
62
63
}
63
64
});
64
65
}
65
66
66
67
private void handleGushici (RoutingContext routingContext ) {
67
68
// 这里有两层回调,因为第二层回调需要用到第一层回调的数据。
68
- parseURI (routingContext . normalisedPath () ) // 获取到 URI 上面的参数
69
+ parseURI (routingContext ) // 获取到 URI 上面的参数
69
70
.setHandler (params -> {
70
71
if (params .succeeded ()) {
71
72
vertx .eventBus ().<String >send (Key .GET_GUSHICI_FROM_REDIS , params .result (), res -> { // 从 Redis 拿数据
72
73
if (res .succeeded ()) {
73
74
returnGushici (routingContext , res .result ().body (), params .result ());
74
75
} else {
75
- returnError ( routingContext , res .cause ());
76
+ routingContext . fail ( res .cause ());
76
77
}
77
78
});
78
79
} else {
79
- returnError ( routingContext , params .cause ());
80
+ routingContext . fail ( params .cause ());
80
81
}
81
82
});
82
83
}
@@ -86,7 +87,7 @@ private void showLog(RoutingContext routingContext) {
86
87
if (res .succeeded ()) {
87
88
returnJson (routingContext , res .result ().body ());
88
89
} else {
89
- returnError ( routingContext , res .cause ());
90
+ routingContext . fail ( res .cause ());
90
91
}
91
92
});
92
93
}
@@ -104,15 +105,19 @@ private void returnJsonWithCache(RoutingContext routingContext, JsonObject jsonO
104
105
.end (jsonObject .encodePrettily ());
105
106
}
106
107
107
- private void returnError (RoutingContext routingContext , Throwable cause ) {
108
+ private void returnError (RoutingContext routingContext ) {
108
109
JsonObject result = new JsonObject ();
109
- result .put ("error" , cause .getMessage ());
110
- int statusCode = cause .getMessage ().startsWith ("404" ) ? 404 : 500 ;
111
- if (statusCode == 500 ) {
112
- log .error (cause );
110
+ int errorCode = routingContext .statusCode () > 0 ? routingContext .statusCode () : 500 ;
111
+ // 不懂 Vert.x 为什么 EventBus 和 Web 是两套异常系统
112
+ if (routingContext .failure () instanceof ReplyException ) {
113
+ errorCode = ((ReplyException ) routingContext .failure ()).failureCode ();
114
+ }
115
+ result .put ("error-code" , errorCode );
116
+ if (routingContext .failure () != null ) {
117
+ result .put ("reason" , routingContext .failure ().getMessage ());
113
118
}
114
119
setCommonHeader (routingContext .response ()
115
- .setStatusCode (statusCode )
120
+ .setStatusCode (errorCode )
116
121
.putHeader ("content-type" , "application/json; charset=utf-8" ))
117
122
.end (result .encodePrettily ());
118
123
}
@@ -146,15 +151,14 @@ private void returnGushici(RoutingContext routingContext, String obj, JsonObject
146
151
.putHeader ("Content-Length" , res .result ().length () + "" )
147
152
.write (res .result ()).end ();
148
153
} else {
149
- returnError ( routingContext , res .cause ());
154
+ routingContext . fail ( res .cause ());
150
155
}
151
156
});
152
157
break ;
153
158
}
154
159
default :
155
- returnError ( routingContext , new Exception ( "参数错误" ));
160
+ routingContext . fail ( new ReplyException ( ReplyFailure . RECIPIENT_FAILURE , 400 , "参数错误" ));
156
161
}
157
-
158
162
}
159
163
160
164
private HttpServerResponse setCommonHeader (HttpServerResponse response ) {
@@ -173,56 +177,27 @@ private void log(RoutingContext routingContext) {
173
177
174
178
/**
175
179
* 根据 uri 获取参数
176
- *
177
- * @param uri 例如:/shenghuo/buyi.png, /all
178
- * @return {format: "png", classes: [shenghuo, buyi]}, {format:"json", classes:[""]}
180
+ * @param routingContext example: uri: /shenghuo/buyi.png , /all
181
+ * @return {format: "png", categories: [shenghuo, buyi]}, {format:"json", categories:[""]}
179
182
*/
180
- private Future <JsonObject > parseURI (String uri ) {
183
+ private Future <JsonObject > parseURI (RoutingContext routingContext ) {
181
184
Future <JsonObject > result = Future .future ();
182
- if (uri .length () > 100 ) {
183
- result .fail (new IllegalArgumentException ("参数太长了,别玩了" ));
184
- return result ;
185
- }
186
-
187
- JsonObject pathParams = new JsonObject ();
188
-
189
- String rawClasses ;
190
- String rawFormat = "" ;
191
-
192
- if (uri .contains ("." )) {
193
- Pattern pattern = Pattern .compile ("/(.*)\\ .(.*)" );
194
- Matcher m = pattern .matcher (uri );
195
- if (!m .find ()) {
196
- result .fail (new IllegalArgumentException ("非法参数" ));
197
- return result ;
198
- }
199
- rawClasses = m .group (1 );
200
- rawFormat = m .group (2 );
201
- } else {
202
- rawClasses = uri .replaceFirst ("/" , "" );
203
- }
204
-
205
-
206
- String [] classes = rawClasses .split ("/" );
207
- if (classes .length < 1 ) {
208
- result .fail (new IllegalArgumentException ("非法参数" ));
209
- return result ;
210
- }
211
- classes [0 ] = classes [0 ].replaceFirst ("all" , "" );
212
- pathParams .put ("classes" , new JsonArray (Arrays .asList (classes )));
213
185
214
- // 处理文件后缀
186
+ String rawCategory = routingContext .request ().getParam ("param0" );
187
+ String rawFormat = routingContext .request ().getParam ("param1" );
188
+ // 如果是 "all" 则当没有分类处理
189
+ JsonArray categories = new JsonArray (
190
+ Arrays .stream (rawCategory .split ("/" ))
191
+ .filter (s -> !s .isEmpty ())
192
+ .filter (s -> !"all" .equals (s ))
193
+ .collect (Collectors .toList ()));
194
+ // 默认 json
195
+ String format = "" .equals (rawFormat ) ? "json" : rawFormat ;
215
196
216
- String format ;
217
- if (Arrays .asList ("json" , "svg" , "txt" , "png" , "" ).contains (rawFormat )) {
218
- format = "" .equals (rawFormat ) ? "json" : rawFormat ;
219
- } else {
220
- result .fail (new IllegalArgumentException ("非法参数" ));
221
- return result ;
222
- }
197
+ JsonObject pathParams = new JsonObject ();
198
+ pathParams .put ("categories" , categories );
223
199
pathParams .put ("format" , format );
224
-
225
200
result .complete (pathParams );
226
201
return result ;
227
202
}
228
- }
203
+ }
0 commit comments