Is there a way to change the implementation of UriInfo that's injected into all the resources and classes? I want to keep most of the implementation the same, but just change one part of it (the part that provides a UriBuilder - I want to provide a different implementation of the UriBuilder).
You can create wrapper around the original UriInfo
public class MyUriInfo implements UriInfo {
private final UriInfo delegate;
public MyUriInfo(UriInfo uriInfo) {
this.delegate = uriInfo;
}
@Override
public String getPath() {
return delegate.getPath();
}
@Override
public UriBuilder getRequestUriBuilder() {
return new MyUriBuilder();
}
...
}
Then just create a Factory
to return your custom UriInfo
. This Factory
will be used by the DI framework to inject the UriInfo
.
public class MyUriInfoFactory
extends AbstractContainerRequestValueFactory<MyUriInfo> {
@Override
public MyUriInfo provide() {
return new MyUriInfo(getContainerRequest().getUriInfo());
}
}
Then just create the AbstractBinder
and register it with the ResourceConfig
public class Binder extends AbstractBinder {
@Override
protected void configure() {
bindFactory(MyUriInfoFactory.class)
.to(UriInfo.class)
.in(RequestScoped.class)
.proxy(true)
.proxyForSameScope(false)
.ranked(10);
}
}
public class AppConfig extends ResourceConfig {
public AppConfig() {
register(new Binder());
}
}
If you are using web.xml, check out this post.
Now you should be able to just inject it
@GET
public String get(@Context UriInfo uriInfo) {
return uriInfo.getClass().getName();
}
If you want to be able to retain being able to inject the original UriInfo
, you can change the binding to
bindFactory(MyUriInfoFactory.class)
.to(MyUriInfo.class) // <--- Change here to MyUriInfo
.in(RequestScoped.class)
.proxy(true)
.proxyForSameScope(false)
.ranked(10);
This way, you would need to inject MyUriInfo
@GET
public String get(@Context MyUriInfo uriInfo) {
return uriInfo.getClass().getName();
}
Doing this, you are still able to inject the original UriInfo
if you needed to.
See Also: