Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing @Context argument to method in class

I have an existing class I'm trying to hook into to get some header parameters to SSO a user into our system. The class is as follows.

import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;

import org.springframework.stereotype.Component;

@Component
@Path("/http")
public class HttpResource {
    @GET
    @Path("/getHeaders")
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, String> getAllHeaders(@Context HttpHeaders headers) {
        Map<String, String> headerList = new HashMap<String, String>();
        for (String key : headers.getRequestHeaders().keySet()) {
            String value = headers.getRequestHeader(key).get(0);
            System.out.println(key + " : " + value);
            headerList.put(key, value);
        }
        return headerList;
    }
}

What I'm trying to figure out is how do I call getAllHeaders() with the @Context argument? I've found a ton of examples of the class I have, but nothing that shows how to call it.

I've also tried putting the annotation inside the class instead of as an argument.

@Context
HttpHeaders httpHeaders;

but when I try to access httpHeaders.getAllHeaders() it returns null. I assume because it's not actually created because the javax documents say it will never return null.

I'm trying to call this within my SSOAuthorizationFilter.java, but have also tried accessing it via a controller as well.

like image 450
Matt Busche Avatar asked Jul 26 '16 19:07

Matt Busche


1 Answers

Write an Annotation first.

@Retention(RUNTIME)
@Target({ PARAMETER })
@Documented
public @interface SSOAuthorization {}

And then a Resolver for that.

public class SSOAuthorizationResolver {

    public static class SSOAuthorizationInjectionResolver extends
            ParamInjectionResolver<SSOAuthorization> {
        public SSOAuthorizationInjectionResolver() {
            super(SSOAuthorizationValueFactoryProvider.class);
        }
    }


    @Singleton
    public static class SSOAuthorizationValueFactoryProvider extends
            AbstractValueFactoryProvider {

        @Context
        private HttpHeaders httpHeaders;

        @Inject
        public SSOAuthorizationValueFactoryProvider(
                final MultivaluedParameterExtractorProvider mpep,
                final ServiceLocator injector) {
            super(mpep, injector, Parameter.Source.UNKNOWN);
        }

        @Override
        protected Factory<?> createValueFactory(final Parameter parameter) {
            final Class<?> classType = parameter.getRawType();

            if (!Language.class.equals(classType)
                    || parameter.getAnnotation(SSOAuthorization.class) == null) {
                return null;
            }

            return new AbstractContainerRequestValueFactory<String>() {
                @Override
                public String provide() {
                    // Can use httpHeader to get your header here.
                    return httpHeader.getHeaderString("SSOAuthorization");
                }
            };
        }

    }

    // Binder implementation
    public static class Binder extends AbstractBinder {
        @Override
        protected void configure() {

            bind(SSOAuthorizationValueFactoryProvider.class).to(
                    ValueFactoryProvider.class).in(Singleton.class);

            bind(SSOAuthorizationInjectionResolver.class).to(
                    new TypeLiteral<InjectionResolver<SSOAuthorization>>() {
                    }).in(Singleton.class);

        }

    }
}

And in the ResourceConfig just register the Resolver

public class MyResourceConfig extends ResourceConfig {

    public MyResourceConfig(Class... classes) {
        super(classes);
        register(new SSOAuthorizationResolver.Binder());
    }
}

And finally use it in your controller with the @SSOAuthorization annotation.

@GET
@Path("/get")
@Produces(MediaType.APPLICATION_JSON)
public String someMethod(@SSOAuthorization String auth) {
    return auth;
}
like image 114
shazin Avatar answered Oct 04 '22 00:10

shazin