gpt4 book ai didi

java - 未从 VertxResteasyDeployment 调用 JAX-RS DynamicFeature 实现

转载 作者:行者123 更新时间:2023-11-30 02:07:56 27 4
gpt4 key购买 nike

我正在尝试使用 MDC 将每个 http 请求的唯一请求 ID 记录到我的资源中,以进行调试并跟踪特定请求。为此,我创建了一个自定义注释@TagRequestID。以下是日志记录请求 ID。但是我无法实现请求的不是通过 DynamicFilter 实现,我认为 VertxResteasyDeployment 类中应该有一些方法或方式应该有助于解决这个问题。

基本上,即使我尝试使用 VertxResteasyDeployment 类的 setProviders 方法,请求也不会通过过滤器。有人可以指导我在这里缺少什么吗?我相信应该有一些配置请求通过 DynamicFeature 实现传递请求,我们在其中注入(inject) RequestIdConfig bean。 (假设我已经创建了 RequestIdConfig bean)。

@TagRequestID 代码:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TagRequestID {
}

自定义类RequestIdConfig:

import lombok.Data;
import javax.validation.constraints.NotNull;

@Data
public class RequestIdConfig {
@NotNull
private String resourcePackage;

@NotNull
private String requestIdHeaderKey;

@NotNull
private Boolean requestIdMandatoryFlag;
}

自定义类RequestIdFeature:

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.ConstrainedTo;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

@Slf4j
@AllArgsConstructor
@Provider
public class RequestIdFeature
implements DynamicFeature {

RequestIdConfig requestIdConfig;

@Override
public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
log.info("testing now===");

final Class<?> resourceClass = resourceInfo.getResourceClass();
//Check if the current resource is to validated
if (resourceClass.getPackage().getName().startsWith(requestIdConfig.getResourcePackage())) {
//Check if the Validation annotation is present
if (resourceInfo.getResourceMethod().getAnnotation(TagRequestID.class) != null) {
log.info(resourceInfo.getResourceMethod() + " registered for clientID validation");
featureContext.register(new RequestIdFilter(requestIdConfig, resourceInfo));
}
}
}
}

过滤器的自定义类:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jboss.logging.MDC;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.UUID;

@Data
@AllArgsConstructor
@Slf4j
@Provider
public class RequestIdFilter
implements ContainerRequestFilter {

RequestIdConfig requestIdConfig;
ResourceInfo resourceInfo;

public static final String REQUEST_ID = "request-Id";

@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {

log.info("ClientIdValidation filter method invoked");

Method resourceMethod = resourceInfo.getResourceMethod();

// Validate Clients
validatePermissions(containerRequestContext);
}

private void validatePermissions(final ContainerRequestContext containerRequestContext) {
String requestId = containerRequestContext.getHeaderString(requestIdConfig.getRequestIdHeaderKey());

//Make sure the Header key is present if mandatory flag is true
if (requestIdConfig.getRequestIdMandatoryFlag() && StringUtils.isAnyEmpty(requestId)) {
throw new WebApplicationException(requestIdConfig.getRequestIdHeaderKey() + " can't be null", Response.Status.UNAUTHORIZED);
}

//If no request ID present, generate a UUID
if (StringUtils.isAnyEmpty(requestId)) {
requestId = UUID.randomUUID()
.toString();
}

containerRequestContext.setProperty(REQUEST_ID, requestId);
MDC.put(REQUEST_ID, requestId);
}
}

资源或 Controller 代码:

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import io.vertx.core.Vertx;
import io.vertx.core.WorkerExecutor;

public class Processor {
@POST
@TagRequestID
@Path("/update_record")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON })
public void updateEvent(String data) throws Exception{
//do something here
}

我们运行此代码的服务器代码:

import mypackage.Processor;
import io.vertx.core.AbstractVerticle;
import org.jboss.resteasy.plugins.server.vertx.VertxRequestHandler;
import org.jboss.resteasy.plugins.server.vertx.VertxResteasyDeployment;
import org.springframework.context.ApplicationContext;


public class VertxServer extends AbstractVerticle {
VertxServer(final ApplicationContext context) {
}

@Override
public void start() throws Exception {
VertxResteasyDeployment deployment = new VertxResteasyDeployment();
deployment.start();
deployment.getRegistry().addPerInstanceResource(Processors.class);
vertx.createHttpServer()
.requestHandler(new VertxRequestHandler(vertx, deployment))
.listen(8080);
}
}

服务器启动并运行后,只需在上述 Controller 上同时发出两个请求即可。即:

curl -X POST \ http://localhost:8080/v1/update_record \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \
-H 'Postman-Token: c9494189-4ac9-9f6c-44f6-216186c74431' \ -d '{"id":"123"}'

最佳答案

VertxServer.java中,在注册资源之前在providerFactory中注册您的dynamicFeature实例。在注册资源时将使用在providerFactory中注册的动态功能和过滤器。

您的代码将如下所示:

VertxResteasyDeployment deployment = new VertxResteasyDeployment();
deployment.start();
deployment.getProviderFactory().register(new RequestIdFeature(getRequiredBean());
deployment.getRegistry().addPerInstanceResource(Processors.class);
vertx.createHttpServer()
.requestHandler(new VertxRequestHandler(vertx, deployment))
.listen(8080);

关于java - 未从 VertxResteasyDeployment 调用 JAX-RS DynamicFeature 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50966514/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com