vida versiculos versiculo significado señor real para nombre invocar etimologico dios como java jersey jersey-1.0

java - versiculos - significado de invocar



¿Cómo hacer que el método de recursos coincida con el URI antes de que Jersey lo invoque? (4)

Estoy intentando implementar un ContainerRequestFilter que realiza la validación personalizada de los parámetros de una solicitud. Necesito buscar el método de recursos que coincidirá con el URI para poder eliminar las anotaciones personalizadas de los parámetros del método.

Sobre la base de esta respuesta , debería poder inyectar ExtendedUriInfo y luego usarlo para que coincida con el método:

public final class MyRequestFilter implements ContainerRequestFilter { @Context private ExtendedUriInfo uriInfo; @Override public ContainerRequest filter(ContainerRequest containerRequest) { System.out.println(uriInfo.getMatchedMethod()); return containerRequest; } }

Pero, getMatchedMethod parecer, getMatchedMethod devuelve un null , hasta que se invoca el método (en ese momento es demasiado tarde para que haga la validación).

¿Cómo puedo recuperar el Method que se comparará con un URI determinado antes de invocar el método de recursos?

Para aquellos interesados, estoy intentando rodar mi propia validación de parámetros requerida, como se describe en JERSEY-351 .


Descubrí cómo resolver mi problema usando solo Jersey. Aparentemente, no hay forma de hacer coincidir el URI de una solicitud con el método que se combinará antes de invocar ese método, al menos en Jersey 1.x. Sin embargo, pude usar un ResourceFilterFactory para crear un ResourceFilter para cada método de recurso individual; de esa manera, estos filtros pueden conocer el método de destino con anticipación.

Aquí está mi solución, incluida la validación para los parámetros de consulta necesarios (utiliza Guava y JSR 305):

public final class ValidationFilterFactory implements ResourceFilterFactory { @Override public List<ResourceFilter> create(AbstractMethod abstractMethod) { //keep track of required query param names final ImmutableSet.Builder<String> requiredQueryParamsBuilder = ImmutableSet.builder(); //get the list of params from the resource method final ImmutableList<Parameter> params = Invokable.from(abstractMethod.getMethod()).getParameters(); for (Parameter param : params) { //if the param isn''t marked as @Nullable, if (!param.isAnnotationPresent(Nullable.class)) { //try getting the @QueryParam value @Nullable final QueryParam queryParam = param.getAnnotation(QueryParam.class); //if it''s present, add its value to the set if (queryParam != null) { requiredQueryParamsBuilder.add(queryParam.value()); } } } //return the new validation filter for this resource method return Collections.<ResourceFilter>singletonList( new ValidationFilter(requiredQueryParamsBuilder.build()) ); } private static final class ValidationFilter implements ResourceFilter { final ImmutableSet<String> requiredQueryParams; private ValidationFilter(ImmutableSet<String> requiredQueryParams) { this.requiredQueryParams = requiredQueryParams; } @Override public ContainerRequestFilter getRequestFilter() { return new ContainerRequestFilter() { @Override public ContainerRequest filter(ContainerRequest request) { final Collection<String> missingRequiredParams = Sets.difference( requiredQueryParams, request.getQueryParameters().keySet() ); if (!missingRequiredParams.isEmpty()) { final String message = "Required query params missing: " + Joiner.on(", ").join(missingRequiredParams); final Response response = Response .status(Status.BAD_REQUEST) .entity(message) .build(); throw new WebApplicationException(response); } return request; } }; } @Override public ContainerResponseFilter getResponseFilter() { return null; } } }

Y ResourceFilterFactory está registrado en Jersey como un parámetro de inicio del servlet en web.xml :

<init-param> <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name> <param-value>my.package.name.ValidationFilterFactory</param-value> </init-param>

En el inicio, se llama a ValidationFilterFactory.create por cada método de recurso detectado por Jersey.

El crédito va a esta publicación para que me guíe por el camino correcto: ¿Cómo puedo obtener las anotaciones de recursos en un contenedor de Jersey?


En realidad, debe intentar inyectar ResourceInfo en su filtro de solicitud personalizado. Lo he probado con RESTEasy y funciona allí. La ventaja es que usted codifica contra las interfaces JSR y no la implementación de Jersey.

public class MyFilter implements ContainerRequestFilter { @Context private ResourceInfo resourceInfo; @Override public void filter(ContainerRequestContext requestContext) throws IOException { Method theMethod = resourceInfo.getResourceMethod(); return; } }


En resteasy-jaxrs-3.0.5, puede recuperar un ResourceMethodInvoker representa el método de recurso coincidente de ContainerRequestContext.getProperty() dentro de un ContainerRequestFilter :

import org.jboss.resteasy.core.ResourceMethodInvoker; public class MyRequestFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext request) throws IOException { String propName = "org.jboss.resteasy.core.ResourceMethodInvoker"; ResourceMethodInvoker invoker = (ResourceMethodInvoker)request.getProperty(); invoker.getMethod().getParameterTypes().... } }


Sé que estás buscando una solución exclusiva de Jersey, pero aquí hay un enfoque de Guice que debería hacer que las cosas funcionen:

public class Config extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector( new JerseyServletModule() { @Override protected void configureServlets() { bindInterceptor(Matchers.inSubpackage("org.example"), Matchers.any(), new ValidationInterceptor()); bind(Service.class); Map<String, String> params = Maps.newHashMap(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example"); serve("/*").with(GuiceContainer.class, params); } }); } public static class ValidationInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation method) throws Throwable { System.out.println("Validating: " + method.getMethod()); return method.proceed(); } } }

@Path("/") public class Service { @GET @Path("service") @Produces({MediaType.TEXT_PLAIN}) public String service(@QueryParam("name") String name) { return "Service " + name; } }

EDITAR: Una comparación de rendimiento:

public class AopPerformanceTest { @Test public void testAopPerformance() { Service service = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bindInterceptor(Matchers.inSubpackage("org.example"), Matchers.any(), new ValidationInterceptor()); } }).getInstance(Service.class); System.out.println("Total time with AOP: " + timeService(service) + "ns"); } @Test public void testNonAopPerformance() { System.out.println("Total time without AOP: " + timeService(new Service()) + "ns"); } public long timeService(Service service) { long sum = 0L; long iterations = 1000000L; for (int i = 0; i < iterations; i++) { long start = System.nanoTime(); service.service(null); sum += (System.nanoTime() - start); } return sum / iterations; } }