当前位置: 首页 > 面试题库 >

球衣2:如何创建自定义HTTP参数绑定

谢昊乾
2023-03-14
问题内容

我正在尝试为我的宁静服务创建自定义的http参数绑定。请参见下面的示例。

@POST
@Path("/user/{userId}/orders")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public MyResult foo(@PathParam("userId") String someString, @UserAuthHeaderParam String authString){

}

您可以看到函数签名中有一个UserAuthHeaderParam批注。我想做的是有一个自定义的http参数绑定,而不是标准的javax.ws.rs。*
Param。

我尝试实现org.glassfish.hk2.api.InjectionResolver,它基本上从http标头中提取值:

public class ProtoInjectionResolver implements InjectionResolver<UserAuthHeaderParam>{
...
@Override
public Object resolve(Injectee injectee, ServiceHandle< ? > root)
{

    return "Hello World";
}
...

}

当我调用restful服务时,服务器出现以下异常。它表明框架无法解析函数签名中的参数:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=String,parent=MyResource,qualifiers={}),position=0,optional=false,self=false,unqualified=null,2136594195),

java.lang.IllegalArgumentException: While attempting to resolve the dependencies of rs.server.MyResource errors were found

请帮忙。任何建议表示赞赏。我的确在Google上进行了大量搜索,但无法正常工作。Jersey 2. 。如何替换Jersey 1.

的InjectableProvider和AbstractHttpContextInjectable可能是类似的问题。

-更新:我使用AbstractBinder将解析器绑定到UserAuthHeaderParam:

public class MyApplication extends ResourceConfig
{

public MyApplication()
{
    register(new AbstractBinder()
    {
        @Override
        protected void configure()
        {
            // bindFactory(UrlStringFactory.class).to(String.class);
            bind(UrlStringInjectResolver.class).to(new TypeLiteral<InjectionResolver<UrlInject>>()
            {
            }).in(Singleton.class);
        }
    });
    packages("rs");

}

}

谢谢!


问题答案:

如果只需要将值直接从标头传递给方法,则无需创建自定义注释。假设您有一个标头Authorization,则可以通过这样声明您的方法来轻松访问它:

@GET
public String authFromHeader(@HeaderParam("Authorization") String authorization) {
    return "Header Value: " + authorization + "\n";
}

您可以通过调用进行测试curl,例如

$ curl --header "Authorization: 1234" http://localhost:8080/rest/resource
Header Value: 1234

鉴于您的问题的答案,如何创建自定义绑定如下。

首先,您必须像这样声明您的注释:

@java.lang.annotation.Target(PARAMETER)
@java.lang.annotation.Retention(RUNTIME)
@java.lang.annotation.Documented
public @interface UserAuthHeaderParam {
}

声明注释后,您必须定义如何解决它。声明值工厂提供程序(在这里可以访问标头参数-请参阅我的评论):

@Singleton
public class UserAuthHeaderParamValueFactoryProvider extends AbstractValueFactoryProvider {

    @Inject
    protected UserAuthHeaderParamValueFactoryProvider(MultivaluedParameterExtractorProvider mpep, ServiceLocator locator) {
        super(mpep, locator, Parameter.Source.UNKNOWN);
    }

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

        if (classType == null || (!classType.equals(String.class))) {
            return null;
        }

        return new AbstractHttpContextValueFactory<String>() {
            @Override
            protected String get(HttpContext httpContext) {
                // you can get the header value here
                return "testString";
            }
        };
    }
}

现在声明一个注入解析器

public class UserAuthHeaderParamResolver extends ParamInjectionResolver<UserAuthHeaderParam> {
    public UserAuthHeaderParamResolver() {
        super(UserAuthHeaderParamValueFactoryProvider.class);
    }
}

和用于您的配置的活页夹

public class HeaderParamResolverBinder extends AbstractBinder {

    @Override
    protected void configure() {
        bind(UserAuthHeaderParamValueFactoryProvider.class)
                .to(ValueFactoryProvider.class)
                .in(Singleton.class);

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

现在最后一件事,在您的ResourceConfig add中register(new HeaderParamResolverBinder()),像这样

@ApplicationPath("rest")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        register(new HeaderParamResolverBinder());
        packages("your.packages");
    }
}

鉴于此,您现在应该能够根据需要使用该值:

@GET
public String getResult(@UserAuthHeaderParam String param) {
    return "RESULT: " + param;
}

我希望这有帮助。



 类似资料:
  • 问题内容: 我正在http://www.cafeaulait.org/javafaq.html上阅读#6.10项,然后我开始怀疑大型企业如何创建自己的JVM实现。一个人会尝试(或可行)实验性的东西吗? 问题答案: 从技术上讲,创建该新JVM所需的所有信息都是该语言和目标平台的公共规范。即使字节码解释在很大程度上相同,JVM还是需要根据其是要在台式机还是手机上运行而有所不同。 一些开始寻找信息的地方

  • 本文向大家介绍Angular 2 创建自定义管道,包括了Angular 2 创建自定义管道的使用技巧和注意事项,需要的朋友参考一下 示例 app / pipes.pipe.ts app / my-component.component.ts            

  • 每次点击都要获取最新的goodsId,当前这个写法只能获取初始的goodsId: 100,自定义指令无法获取到goodsId的最新值。 尝试过的方法: 1、在updated内再一次获取最新值,但是每次点击,事件会触发多次。 2、在vnode上获取最新值,同样无法获取到最新值。 在此想请教一下各位

  • 我使用Jersey 2.10异常映射器类来处理异常。我想返回错误状态和错误信息的JSON正文。我想得到类似的回应: Jersey没有在响应中发送JSON正文。我得到的是: 如果我将状态代码更改为200,那么我将获得预期的响应正文 请帮我找出这个问题的解决方案。 异常映射器在错误对象中填充错误消息和状态。以下是异常映射程序代码: 这是来自错误对象的代码:

  • 本文向大家介绍Android如何创建自定义ActionBar,包括了Android如何创建自定义ActionBar的使用技巧和注意事项,需要的朋友参考一下 当多个界面都有很多相似部分时,可以考虑创建一个功能较全的模板。而在需要时,可以通过引用模板来实现自己想要实现的功能。比如适配器 Adapter,当很多的适配器都差不多时,就可以通过打造一个通用的适配器来实现。本例中主要是如何创建自定义的 Act

  • 标题说明了一切。我想创建一个自定义的prestashop页面,但我不知道如何创建。我真正想做的是:创建一个按钮,打开一个自定义页面。我在网上找不到任何有用的东西,所以我来这里寻求帮助。有人能告诉我怎么做吗?