tipos página pagina otra misma imagen hipervinculos hipervinculo hacer etiquetas etiqueta enlaces enlace ejemplos dentro como java jersey-2.0 grizzly

java - página - jersey 2: Cómo crear un enlace personalizado de parámetros HTTP



href html ejemplos (4)

Estoy tratando de crear un enlace personalizado de http param para mi servicio de descanso. Por favor, vea el ejemplo a continuación.

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

Puede ver que hay una anotación UserAuthHeaderParam en la firma de función. Lo que quiero hacer es tener un enlace de param http personalizado distinto del estándar javax.ws.rs. * Param.

He intentado implementar org.glassfish.hk2.api.InjectionResolver que básicamente extrae el valor del encabezado http:

public class ProtoInjectionResolver implements InjectionResolver<UserAuthHeaderParam>{ ... @Override public Object resolve(Injectee injectee, ServiceHandle< ? > root) { return "Hello World"; } ... }

Cuando llamo al servicio de descanso, el servidor recibe las siguientes excepciones. Indica que el marco no puede resolver el parámetro en la firma de función:

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

Por favor ayuda. Cualquier consejo es apreciado. Hago mucha búsqueda en google pero no puedo hacer que funcione. Jersey 2. *. Cómo reemplazar InjectableProvider y AbstractHttpContextInjectable of Jersey 1. * podría ser la pregunta similar.

- ACTUALIZACIONES: uso AbstractBinder para enlazar mi resolución a 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"); } }

¡Gracias!


Aquí está mi implementación real de la clase UserAuthHeaderParamValueFactoryProvider

import javax.inject.Inject; import javax.inject.Singleton; import org.glassfish.hk2.api.Factory; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory; import org.glassfish.jersey.server.internal.inject.AbstractValueFactoryProvider; import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider; import org.glassfish.jersey.server.model.Parameter; @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 AbstractContainerRequestValueFactory<String>() { @Override public String provide() { //you can use get any header value. return getContainerRequest().getHeaderString("Authorization"); } }; }


No sé cómo resolver su excepción. Sin embargo, puedo proponerle una manera diferente de hacer lo mismo. Espero que ayude.

He enfrentado exactamente el mismo problema: necesito parámetros adicionales en el encabezado http (por cierto, también relacionado con la autenticación). Además, debo enviarlos en cada llamada, ya que quiero hacer una implementación de descanso "típica", sin mantener una sesión.

Estoy usando Jersey 2.7, pero diría que debería funcionar en 2.0. He seguido su documentación https://jersey.java.net/documentation/2.0/filters-and-interceptors.html

Está bastante claro allí, pero de todos modos copio y pego mi implementación a continuación. Funciona bien. Es cierto que hay otras formas de asegurar un servicio de descanso, por ejemplo, esta es una buena: http://www.objecthunter.net/tinybo/blog/articles/89

Pero dependen de la implementación del servidor de aplicaciones y de la base de datos que utilice. El filtro, en mi opinión, es más flexible y más fácil de implementar.

Copiar y pegar: he definido un filtro para la autenticación, que se aplica a cada llamada y se ejecuta antes del servicio (gracias a @PreMatching ).

@PreMatching public class AuthenticationRequestFilter implements ContainerRequestFilter { @Override public void filter(final ContainerRequestContext requestContext) throws IOException { final MultivaluedMap<String, String> headers = requestContext.getHeaders(); if (headers == null) { throw new... } // here I get parameters from the header, via headers.get("parameter_name") // In particular, I get the profile, which I plan to use as a Jersey role // then I authenticate // finally, I inform the Principal and the role in the SecurityContext object, so that I can use @RolesAllowed later requestContext.setSecurityContext(new SecurityContext() { @Override public boolean isUserInRole(final String arg0) { //... } @Override public boolean isSecure() { //... } @Override public Principal getUserPrincipal() { //... } @Override public String getAuthenticationScheme() { //... } }); } }

Debe incluir esta clase de filtro en su implementación de ResourceConfig ,

public class MyResourceConfig extends ResourceConfig { public MyResourceConfig() { // my init // my packages register(AuthenticationRequestFilter.class); // filtro de autenticación // other register } }

¡Espero eso ayude!


Si lo que necesita es recuperar todos los encabezados http vinculados en un objeto, una solución podría ser usar la anotación @Context para obtener javax.ws.rs.core.HttpHeaders ; que contiene la lista de todos los encabezados de solicitud.

@POST @Path("/user/{userId}/orders") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public MyResult foo(@PathParam("userId") String someString, @Context HttpHeaders headers){ // You can list all available HTTP request headers via following code : for(String header : headers.getRequestHeaders().keySet()){ System.out.println(header); } }


Si todo lo que desea es pasar el valor directamente del encabezado al método, no necesita crear anotaciones personalizadas. Supongamos que tiene una Authorization encabezado, luego puede acceder a ella fácilmente declarando su método así:

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

Puedes probarlo llamando a curl , por ejemplo

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

Dado que la respuesta a su pregunta, cómo crear un enlace personalizado es la siguiente.

Primero tienes que declarar tu anotación así:

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

Una vez declarada su anotación, debe definir cómo se resolverá. Declare el Value Factory Provider (aquí es donde tendrá acceso a los parámetros del encabezado, vea mi comentario):

@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"; } }; } }

Ahora declara un resolutor de inyección.

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

y un cuaderno para su configuración.

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); } }

ahora lo último, en tu ResourceConfig agregar register(new HeaderParamResolverBinder()) , como este

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

Dado eso, ahora debería poder utilizar el valor como quisiera:

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

Espero que esto ayude.