由于要更改某些功能,因此我试图覆盖某些类的vertx Web项目。所以棘手的部分到了。
@Override
public void reroute(HttpMethod method, String path) {
int split = path.indexOf('?');
if (split == -1) {
split = path.indexOf('#');
}
if (split != -1) {
log.warn("Non path segment is not considered: " + path.substring(split));
// reroute is path based so we trim out the non url path parts
path = path.substring(0, split);
}
/*((HttpServerRequestWrapper) request).setMethod(method);
((HttpServerRequestWrapper) request).setPath(path);*/
((HttpServerRequestWrapper) request).setMethod(method);
((HttpServerRequestWrapper) request).setPath(path);
request.params().clear();
// we need to reset the normalized path
normalisedPath = null;
// we also need to reset any previous status
statusCode = -1;
// we need to reset any response headers
response().headers().clear();
// special header case cookies are parsed and cached
if (cookies != null) {
cookies.clear();
}
// reset the end handlers
if (headersEndHandlers != null) {
headersEndHandlers.clear();
}
if (bodyEndHandlers != null) {
bodyEndHandlers.clear();
}
failure = null;
restart();
}
这段代码抛出一个编译错误:
'HttpServerRequestWrapper cannot be accessed from outside package'
我知道我们可以使用反射来创建无法访问的类的对象。在这种情况下可以使用反射吗?我该如何解决这个问题。
任何帮助将不胜感激。
答案 0 :(得分:1)
如何获取Class
对象,然后在您的特定(未铸造)对象上调用方法?
我假设request
是类型HttpServerRequestWrapper
的类属性。然后,这就是我的建议:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
...
private final Method setMethod;
private final Method setPath;
public MyConstructor() {
Method tmp1 = null, tmp2 = null;
try {
final Class<?> clazz = Class.forName("io.vertx.ext.web.impl.HttpServerRequestWrapper");
tmp1 = clazz.getMethod("setMethod", HttpMethod.class);
tmp1.setAccessible(true);
tmp2 = clazz.getMethod("setPath", String.class);
tmp2.setAccessible(true);
} catch (ClassNotFoundException e) {
// do something
} catch (NoSuchMethodException e) {
// do something
} catch (SecurityException e) {
// do something
}
this.setMethod = tmp1;
this.setPath = tmp2;
}
...
@Override
public void reroute(HttpMethod method, String path) {
...
try {
this.setMethod.invoke(request, method);
this.setPath.invoke(request, path);
} catch (IllegalAccessException e) {
// do something
} catch (IllegalArgumentException e) {
// do something
} catch (InvocationTargetException e) {
// do something
}
...
}
编辑:我根据@GotoFinal的建议更新了此答案。
答案 1 :(得分:1)
在Java 8中和/或没有模块的情况下,可以将与此类相同的类放在与原始类相同的程序包中,以访问所有程序包默认类。
否则,您需要像在其他响应中一样使用反射,但是我要补充一点,最好缓存Class
和Method
实例,就像使用Class.forName
和{{1 }}每次都会降低代码速度。
答案 2 :(得分:0)
看起来HttpServerRequestWrapper实现了HttpServerRequest。因此,您可以在代码中将“ HttpServerRequestWrapper”更改为“ HttpServerRequest”。但是请记住,这样做只能调用接口中指定的方法。
您可以在https://vertx.io/docs/apidocs/io/vertx/rxjava/core/http/HttpServerRequest.html中看到这些方法。