tomcat - 在休息服务中使用注入点失败
问题描述
public class ApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
@Override
protected void configure() {
bind(AuthenticationTokenService.class).to(AuthenticationTokenService.class);
}
}
}
这是泽西岛的注册资源。
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("com.skillsimprover.restexamples.rest");
register(JacksonJsonProvider.class);
register(new ApplicationBinder());
}
}
这是托管 bean
@ApplicationScoped
public class AuthenticationTokenService {
@Inject
private SysLang locale;
@Inject
@Configurable( "authentication.jwt.validFor" )
private Long validFor;
@Inject
@Configurable( "authentication.jwt.refreshLimit" )
private Integer refreshLimit;
@Inject
private AuthenticationTokenIssuer tokenIssuer;
@Inject
private AuthenticationTokenParser tokenParser;
public String issueToken(String username, Set<Authority> authorities) {
String id = generateTokenIdentifier();
ZonedDateTime issuedDate = ZonedDateTime.now();
ZonedDateTime expirationDate = calculateExpirationDate(issuedDate);
AuthenticationTokenDetails tokenDetails = new AuthenticationTokenDetails();
tokenDetails.setId(id);
tokenDetails.setUsername(username);
tokenDetails.setAuthorities(authorities);
tokenDetails.setIssuedDate(issuedDate);
tokenDetails.setExpirationDate(expirationDate);
tokenDetails.setRefreshCount(0);
tokenDetails.setRefreshLimit(refreshLimit);
return tokenIssuer.issueToken(tokenDetails);
}
public AuthenticationTokenDetails parseToken(String token) {
return tokenParser.parseToken(token);
}
public String refreshToken(AuthenticationTokenDetails currentTokenDetails) {
if (!currentTokenDetails.isEligibleForRefreshment()) {
MessageException tokenCannotRefreshed = MessageException.TOKEN_CANNOT_REFRESHED;
final String messageException = getMessageExceptionSys(tokenCannotRefreshed, locale.getLang());
throw new AuthenticationTokenRefreshmentException(messageException);
}
ZonedDateTime issuedDate = ZonedDateTime.now();
ZonedDateTime expirationDate = calculateExpirationDate(issuedDate);
AuthenticationTokenDetails newTokenDetails = new AuthenticationTokenDetails();
newTokenDetails.setId(currentTokenDetails.getId());
newTokenDetails.setUsername(currentTokenDetails.getUsername());
newTokenDetails.setAuthorities(currentTokenDetails.getAuthorities());
newTokenDetails.setIssuedDate(issuedDate);
newTokenDetails.setExpirationDate(expirationDate);
newTokenDetails.setRefreshCount(currentTokenDetails.getRefreshCount() + 1);
newTokenDetails.setRefreshLimit(refreshLimit);
return tokenIssuer.issueToken(newTokenDetails);
}
private Long validFor2 = this.validFor;
private ZonedDateTime calculateExpirationDate(ZonedDateTime issuedDate) {
System.out.println(validFor2);
return issuedDate.plusSeconds(validFor);
}
private String generateTokenIdentifier() {
return UUID.randomUUID().toString();
}
}
这是端点
@Provider
@Produces( MediaType.APPLICATION_JSON )
@Consumes( MediaType.APPLICATION_JSON )
@Path("auth")
public class AuthenticationResource {
@Resource
private WebServiceContext context;
@Inject
private AuthenticationTokenService authenticationTokenService;
private static final String VIEW_URL = "/WEB-INF/pages/home.html";
@POST
@PermitAll
@Path("username")
public Response authenticateUserName(UserCredentials credentials,
@Context HttpServletRequest request) {
UsernamePasswordValidator usernamePasswordValidator = new
UsernamePasswordValidator();
usernamePasswordValidator.validateUsername(credentials, request);
....
pom.xml
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.rest.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.7</version>
</dependency>
<!--CDI-->
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-shaded</artifactId>
<version>3.0.5.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core-impl</artifactId>
<version>3.0.5.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.rest.version}</version>
</dependency>
<!-- Jackson modules -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Java EE-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlets.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
这个类 SysLang
@Dependent
public class SysLang {
private static String lang;
static {
Locale localeDefault = Locale.getDefault();
lang = localeDefault.getLanguage();
}
public SysLang() {
}
public String getLang() {
return lang;
}
}
这是使用 CDI 容器进行管理的类。
库“焊接”实现规范 CDI。我使用特定注释(来自 Scope 类型)安装的所有 Java bean 必须使用 CDI 容器库“Weld”进行管理。但是注入点和生产方法不起作用,一旦我从客户端开始将ajax-queries发送到rest-services,即发送到类AuthenticationResource
此处未注入所需的组件。我收到错误...
org.glassfish.jersey.internal.Errors.logErrors 检测到以下警告:警告:检测到未知 HK2 故障:MultiException stack 1 of 7 org.glassfish.hk2.api.UnsatisfiedDependencyException:SystemInjecteeImpl 处没有可注入的对象( requiredType=SysLang,parent=AuthenticationTokenService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1585822177) at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75 )
为什么?请向我解释如何纠正这个错误以及为什么会出现这个错误
我执行了这个:
public class ApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(SysLang.class).to(SysLang.class);
bind(AuthenticationTokenService.class).to(AuthenticationTokenService.class);
}
}
结果我得到
servlet [com.skillsimprover.restexamples.rest.jersey.common.registrationconfig.JerseyConfig] 在路径 [] 的上下文中的 Servlet.service() 引发异常 [java.lang.NullPointerException],根本原因是 java.lang.NullPointerException
com.skillsimprover.restexamples.rest.jersey.security.service.token。身份验证令牌服务。计算过期日期(AuthenticationTokenService.java:194)
那不是提供数据的工作产生方法。
@ApplicationScoped
public class ConfigurationProducer {
private Properties properties;
@PostConstruct
public void init() {
properties = new Properties();
String path = "/application.properties";
try(InputStream stream = ConfigurationProducer.class.getResourceAsStream(path)) {
if (stream == null) {
throw new RuntimeException("Cannot find application.properties configuration file.");
}
this.properties.load(stream);
} catch (final IOException e) {
throw new RuntimeException("Configuration file cannot be loaded.");
}
}
@Produces
@Configurable
public String produceString(InjectionPoint ip) {
return getStrProperty(ip);
}
@Produces
@Configurable
public Integer produceInteger(InjectionPoint ip) {
return Integer.valueOf(getStrProperty(ip));
}
@Produces
@Configurable
public Long produceLong(InjectionPoint ip) {
return Long.valueOf(getStrProperty(ip));
}
@Produces
@Configurable
public Boolean produceBoolean(InjectionPoint ip) {
return Boolean.valueOf(getStrProperty(ip));
}
private String getStrProperty(InjectionPoint ip){
String key = getKey(ip);
return properties.getProperty(key);
}
private String getKey(InjectionPoint ip) {
Annotated annotated = ip.getAnnotated();
Configurable annotation = annotated.getAnnotation(Configurable.class);
return annotation.value();
}
}
Authenticationresource 类使用注解@Produces 和@Inject,HK2 不明白怎么处理??
Weld 也使用相同的注释。怎样成为?
解决方案
推荐阅读
- python - 如何让 Python random.randrange 更高效地生成大范围随机数
- mongodb - 从数组到 Kafka 主题的值
- c# - 通过 DI 注入到 ServiceBusTrigger Azure 函数中的 IHttpClientFactory 是否为每个触发器重用或重新创建?
- python - 如何从 python 脚本运行终端命令并将输出保存到 .csv 文件中?
- excel - 如何获得动态单元格列表的最大值?
- java - 将一个列表项添加到另一个列表
- java - 调用方法时处理第二个 PApplet 窗口不更新
- java - 如何在android 11中将图像保存在外部SDCARD的DCIM文件夹中?
- excel - Excel:从没有 VBA 的列中导出值
- css - SASS 媒体查询问题。无法添加scss