动态参数作为 Apache HttpCore 请求 URI 的一部分
Dynamic parameter as part of request URI with Apache HttpCore
我正在寻找将动态参数与 HttpCore 相匹配的现有解决方案。我想到的是类似于 ruby 对 rails 的约束,或带有风帆的动态参数(例如参见 [=16=])。
我的 objective 是定义一个 REST API,我可以在其中轻松匹配 GET /objects/<object_id>
等请求。
为了提供一点上下文,我有一个使用以下代码创建 HttpServer
的应用程序
server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("MyAppServer/1.1")
.setSocketConfig(socketConfig)
.registerHandler("*", new HttpHandler(this))
.create();
和HttpHandler
class匹配请求的URI并将其分派给相应的后端方法:
public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) {
String method = request.getRequestLine().getMethod().toUpperCase(Locale.ROOT);
// Parameters are ignored for the example
String path = request.getRequestLine().getUri();
if(method.equals("POST") && path.equals("/object/add") {
if(request instanceof HttpEntityEnclosingRequest) {
addObject(((HttpEntityEnclosingRequest)request).getEntity())
}
[...]
当然我可以用 RegEx 更复杂的东西替换 path.equals("/object/add")
来匹配这些动态参数,但在这样做之前我想知道我是否没有重新发明轮子,或者是否有一个existing lib/class 我没有在文档中看到可以帮助我的东西。
使用 HttpCore 是一项要求(它已经集成在我正在处理的应用程序中),我知道其他一些库提供 high-level 支持这些动态参数的路由机制,但我真的负担不起将整个服务器代码切换到另一个库。
我目前使用的是 httpcore 4.4.10,但我可以升级到更新的版本,这可能对我有帮助。
目前 HttpCore 没有功能齐全的请求路由层。 (这样做的原因更多是政治原因而不是技术原因)。
考虑使用自定义 HttpRequestHandlerMapper
来实现应用程序特定的请求路由逻辑。
final HttpServer server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("Test/1.1")
.setSocketConfig(socketConfig)
.setSslContext(sslContext)
.setHandlerMapper(new HttpRequestHandlerMapper() {
@Override
public HttpRequestHandler lookup(HttpRequest request) {
try {
URI uri = new URI(request.getRequestLine().getUri());
String path = uri.getPath();
// do request routing based on the request path
return new HttpFileHandler(docRoot);
} catch (URISyntaxException e) {
// Provide a more reasonable error handler here
return null;
}
}
})
.setExceptionLogger(new StdErrorExceptionLogger())
.create();
我正在寻找将动态参数与 HttpCore 相匹配的现有解决方案。我想到的是类似于 ruby 对 rails 的约束,或带有风帆的动态参数(例如参见 [=16=])。
我的 objective 是定义一个 REST API,我可以在其中轻松匹配 GET /objects/<object_id>
等请求。
为了提供一点上下文,我有一个使用以下代码创建 HttpServer
的应用程序
server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("MyAppServer/1.1")
.setSocketConfig(socketConfig)
.registerHandler("*", new HttpHandler(this))
.create();
和HttpHandler
class匹配请求的URI并将其分派给相应的后端方法:
public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) {
String method = request.getRequestLine().getMethod().toUpperCase(Locale.ROOT);
// Parameters are ignored for the example
String path = request.getRequestLine().getUri();
if(method.equals("POST") && path.equals("/object/add") {
if(request instanceof HttpEntityEnclosingRequest) {
addObject(((HttpEntityEnclosingRequest)request).getEntity())
}
[...]
当然我可以用 RegEx 更复杂的东西替换 path.equals("/object/add")
来匹配这些动态参数,但在这样做之前我想知道我是否没有重新发明轮子,或者是否有一个existing lib/class 我没有在文档中看到可以帮助我的东西。
使用 HttpCore 是一项要求(它已经集成在我正在处理的应用程序中),我知道其他一些库提供 high-level 支持这些动态参数的路由机制,但我真的负担不起将整个服务器代码切换到另一个库。
我目前使用的是 httpcore 4.4.10,但我可以升级到更新的版本,这可能对我有帮助。
目前 HttpCore 没有功能齐全的请求路由层。 (这样做的原因更多是政治原因而不是技术原因)。
考虑使用自定义 HttpRequestHandlerMapper
来实现应用程序特定的请求路由逻辑。
final HttpServer server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("Test/1.1")
.setSocketConfig(socketConfig)
.setSslContext(sslContext)
.setHandlerMapper(new HttpRequestHandlerMapper() {
@Override
public HttpRequestHandler lookup(HttpRequest request) {
try {
URI uri = new URI(request.getRequestLine().getUri());
String path = uri.getPath();
// do request routing based on the request path
return new HttpFileHandler(docRoot);
} catch (URISyntaxException e) {
// Provide a more reasonable error handler here
return null;
}
}
})
.setExceptionLogger(new StdErrorExceptionLogger())
.create();