0

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).

1 Answers1

1

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:

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720