当前位置: 首页 > 知识库问答 >
问题:

泽西:PerRequest estTypeInject tableProvider未被选中

嵇星海
2023-03-14

使用泽西1.17.1,我实现了一个基本的RESTful API并将其部署为Google App Engine 1.7.5中的servlet。我正在使用在HTTP请求标头参数中传输的令牌对用户进行身份验证。我成功地使用@HeaderParam提取令牌并使用令牌对用户进行身份验证,但我想创建一个自定义注释来为我处理身份验证。但是,提供者似乎没有被泽西选中。

我定义注释:

package com.kwogger.api.web.rs.ext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthUser {
  boolean required() default true;
}

和提供商:

package com.kwogger.api.web.rs.ext;

import com.googlecode.objectify.Key;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
import com.kwogger.om.User;

@Provider
public class AuthUserProvider extends PerRequestTypeInjectableProvider<AuthUser, Key<User>> {
  public AuthUserProvider() {
    super(Key.class);
  }

  @Override
  public Injectable<Key<User>> getInjectable(ComponentContext ic, final AuthUser a) {
    return new AbstractHttpContextInjectable<Key<User>>() {
      @Override
      public Key<User> getValue(HttpContext ctxt) {
        // ... authenticate user here ...
      }
    };
  }
}

在我的资源中,我修改了以下endpoint:

  @GET
  public JsonNode getVault() {
    Key<User> user = authUser();
  }

  private String userToken;

  @HeaderParam(Constants.HEADER_USER_TOKEN)
  public void setUserToken(String token) {
    if (token != null) {
      userToken = token;
    }
  }

  @CookieParam(Constants.COOKIE_USER_TOKEN)
  public void setUserTokenCookie(String cookie) {
    if (cookie != null) {
      userToken = cookie;
    }
  }

  private Key<User> authUser() {
    // ... authenticate user here ...
  }

对此:

  @GET
  public JsonNode getItem(@AuthUser Key<User> user) {
    // do stuff...
  }

但是,当我尝试访问endpoint时,我会在日志中收到带有以下错误消息的HTTP 415:

com.sun.jersey.spi.container.ContainerRequest getEntity: A message body reader for Java class com.googlecode.objectify.Key, and Java type com.googlecode.objectify.Key<com.kwogger.om.User>, and MIME media type application/octet-stream was not found.
The registered message body readers compatible with the MIME media type are:
application/octet-stream ->
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.RenderedImageProvider
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader

同一资源文件中的其他每个endpoint都可以正常工作。我已经在com中指定了包。太阳运动衫配置。所有物servlet定义中的包init param,以及与自定义提供程序工作在同一个包中的ExceptionMapper。我没有使用Spring或Guice。

我错过了什么?看起来泽西试图读取Key


共有1个答案

慕阳
2023-03-14

您的密钥

public AuthUserProvider() {
    super(Key.class);
}

但是您正在尝试注入参数化类型,因此您需要适当地调用超类构造函数。获取所需实际类型的最简单(也可能是唯一)方法是通过超类型令牌。下面是一个使用JacksonType参考类作为助手的示例:

public AuthUserProvider() {
    super(new TypeReference<Key<User>>() {
    }.getType());
}

该行:

new TypeReference<Key<User>>() {}.getType()

基本上允许您创建一个保留其泛型信息的类型(在这种情况下,它代表一个Key

除了Jackson TypeReference类之外,您还可以使用Jersey客户端GenericType或Gson TypeToken来完成同样的任务。

 类似资料:
  • 我目前使用的是球衣 我现在要做的是设置泽西,这样当查询参数进来时(比如缩进),我可以告诉Jackson以“更漂亮的格式,也就是缩进”序列化JSON。您可以通过使用SerializationConfig.Feature.INDENT_OUTPUT配置JSON映射器来轻松地告诉Jackson这样做。 问题是,我如何在每个请求的基础上获取一个queryparam并使用它来修改Jackson的输出?

  • 我有一个奇怪的问题,我完全不明白,泽西岛2.6。 我无法解释为什么,但其中一个查询参数使泽西岛抛出模型验证异常 查询参数“一些价值”使球衣投掷: 如果我用String代替SomeValueDTO,一切都没问题。SomeValueDTO是一个非常经典的POJO,带有一个空的构造函数和getter/setter。 如果有人有伊迪亚!!

  • 我在泽西(从文档中)创建了这个测试,它运行良好,但有一个问题:没有被调用。 我需要测试的资源类依赖于ServletContextListener在ServletContext上设置的属性。 我可以确保它被调用吗,或者我可以用其他方式操纵ServletContext吗? 我添加了这些依赖项来实现这一点:

  • 问题内容: 我在Spring启动项目中有一个与Jackson配置有关的问题 如Spring Boot博客中所述 我尝试自定义对象序列化。 在我的配置中添加新的配置bean之后 当我尝试输出类User的实例时,json结果不在CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES中 json输出是: 并不是 也许我需要在Jersey配置中注册一些东西才能激活我的自定义ob

  • 我正在尝试使用JAX-RS(Jersey)构建JSON RESTful Webservice。我也在使用Maven构建应用程序。 我的第一个方法是 pom之后。xml- 所以我补充道 到我的pom文件。其他lib文件(例如jackson-cors-asl-1.7.1.jar、jackson-jaxrs-1.7.1.jar、jaxb impl,…)也可以在生成的war文件中找到//编辑:它还下载st

  • 我正在开发一个REST Web服务,其中我使用URL中的ID来指定患者,如下所示: <代码>WS/服务/患者/1 其中“1”是患者的id。所以,在代码中,我这样指定: 我在一个例子中看到了它,但是我的失败了。我得到了这个错误: 通用域名格式。太阳运动衫应用程序编程接口。容器ContainerException:方法,public void PresentationLayer。PatientReso