servicio restful jax example desde consumir glassfish jersey jackson jax-rs java-ee-7

restful - force glassfish 4 para usar jackson 2.3



jersey client (1)

Escribí una aplicación maven que debería ejecutarse en Glassfish 4.

El ApplicationConfig estándar se ve así:

@javax.ws.rs.ApplicationPath("resources") public class ApplicationConfig extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> resources = new java.util.HashSet<Class<?>>(); // following code can be used to customize Jersey 2.0 JSON provider: try { Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature"); } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, ex); } addRestResourceClasses(resources); return resources; }

El problema ahora es que mis recursos que generan Json deberían usar las anotaciones de jackson 2.3. Pero mi glassfish usa algún codehaus. ... paquetes para proporcionar json. codehaus es la versión anterior de jackson. Quiero usar el nuevo de fasterxml que proporciona la anotación @JsonIdentityInfo.

Pensé que podría resolver mi problema escribiendo:

@javax.ws.rs.ApplicationPath("resources") public class ApplicationConfig extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> resources = new java.util.HashSet<Class<?>>(); resources.add(JacksonFeatures.class); //from the com.fasterxml.jackson.jaxrs.annotation Package resources.add(JacksonJaxbJsonProvider.class); resources.add(JacksonJsonProvider.class); addRestResourceClasses(resources); return resources; }

Pero no tiene efecto. Ahora Glassfish usa el JsonProvider Moxy estándar ... que no quiero usar. ¿Tiene alguna sugerencia de cómo puedo obligar a Glassfish a usar mi biblioteca en lugar de las buildin-libraries? ¿O puedo cambiar la biblioteca Buildin a la más nueva?

Y si sabes cómo resolver esto. ¿podría proporcionar un pequeño fragmento de código?

EDIT 1:

Después de probar el primer enfoque para resolverlo:

nueva ApplicationConfig:

@javax.ws.rs.ApplicationPath("resources") public class ApplicationConfig extends ResourceConfig { public ApplicationConfig() { //register( new GZipEncoder() ); register( JacksonFeature.class ); } private void addMyResources() { //a lot of resources. } }

JacksonFeature:

public class JacksonFeature implements Feature { public boolean configure( final FeatureContext context ) { String postfix = ''.'' + context.getConfiguration().getRuntimeType().name().toLowerCase(); context.property( CommonProperties.MOXY_JSON_FEATURE_DISABLE + postfix, true ); context.register( JsonParseExceptionMapper.class ); context.register( JsonMappingExceptionMapper.class ); context.register( JacksonJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class ); return true; } }

pom:

<dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-base</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-common</artifactId> <version>2.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>2.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> </dependency> </dependencies>

Dependencias:

http://i.stack.imgur.com/uA4V2.png

Error:

SEVERE: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)] org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)] at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403) at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:325) at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177) ...

o

SEVERE: Exception while loading the app SEVERE: Undeployment failed for context /blueserver INFO: file:/C:/bluetrail/blueserver/target/blueserver-0.0.0.1/WEB-INF/classes/_de.bluetrail_blueserver_war_0.0.0.1PU logout successful SEVERE: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [IterableProvider<InjectionResolver<Object>>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 2 of [BackedAnnotatedConstructor] @Inject org.glassfish.jersey.internal.inject.JerseyClassAnalyzer(@Named ClassAnalyzer, IterableProvider<InjectionResolver<Object>>)]

EDICION 2:

Ahora publicaré algunas clases de mi proyecto. En esas clases, incluí todas las Anotaciones que uso.

tengo como 16 entidades como esa:

import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; import java.io.Serializable; import java.sql.Timestamp; import java.util.Set; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.OneToOne; @Entity @JsonIdentityInfo(generator = ObjectIdGenerators.None.class, property = "id", scope=Address.class) //the JsonIdentityInfo is the reason i need Jackson 2 public class Address implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String postalCode; private String city; private String country; private String street; private String houseNumber; @Embedded private Coordinate coordinate; //getters, setters , etc. }

entonces tengo muchos DAO así:

import de.ibs.trail.entity.Address; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateless; @Stateless public class AddressDao extends GenericDao { public Address getAddress(long id){ return em.find(Address.class, id); } public List<Address> getAddresses(){ List<Address> address = em.createQuery("SELECT a FROM Address a", Address.class).getResultList(); return address; } }

y finalmente tengo muchos recursos como este:

import de.bluetrail.blueserver.dao.AddressDao; import de.ibs.trail.entity.Address; import java.util.List; import javax.ejb.Stateless; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; @Path("dummy") @Stateless public class DummyResource { @Context private UriInfo context; @Inject userAuth user; @Inject addressDao AddressDao; public DummyResource() { } @GET @Produces("application/json") public List<Address> getAddress() { return AddressDao.getAddresses(); } }

Esa es la primera parte. Como segunda parte tengo una clase para algunos servicios de Google. Porque quiero tratar de usar Google GeoLocation and Routing. Puse el Google-Code en un archivo pasteBin, porque es muy grande:

http://pastebin.com/u3e0dms6

allí utilizo bibliotecas como:

import com.fasterxml.jackson.databind.ObjectMapper; import de.ibs.trail.entity.Address; //some other entities //... import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.Iterator; import java.util.Set; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient;

Espero que eso ayude. Todas las demás clases usan las mismas anotaciones.


Primero asegúrese de tener lo siguiente en su pom.xml:

<dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>${jackson.version}</version> </dependency>

Luego asegúrate de NO tener esto en ningún pom.xml:

<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.5</version> </dependency>

Entonces necesitas deshabilitar Moxy. La forma más sencilla de hacerlo es abandonar su clase de aplicación y reemplazarla con una clase ResourceConfig. Primero permitamos crear SU clase JacksonFeature:

public class JacksonFeature implements Feature { public boolean configure( final FeatureContext context ) { String postfix = ''.'' + context.getConfiguration().getRuntimeType().name().toLowerCase(); context.property( CommonProperties.MOXY_JSON_FEATURE_DISABLE + postfix, true ); context.register( JsonParseExceptionMapper.class ); context.register( JsonMappingExceptionMapper.class ); context.register( JacksonJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class ); return true; } }

Dos cosas interesantes aquí, primero deshabilité Moxy y segundo me aseguré de agregar los mapeadores JacksonException. De esta forma obtendrá mejores errores que el error interno del servidor si hay una excepción de análisis o generación. Bien, en el último paso, reescribe tu aplicación como una clase ResourceConfig:

@javax.ws.rs.ApplicationPath("resources") public class RestApplication extends ResourceConfig { public RestApplication() { register( new GZipEncoder() ); register( JacksonFeature.class ); } private void addMyResources() { register( MyResource1.class ); register( MyResource2.class ); } }

Deberias hacer eso. Además, en lugar de registrar los recursos uno por uno como este, si conoce su ruta, puede eliminar todo ese código y agregarlo al constructor de RestApplication:

package( "com.me.myrestresourcespackage" );

Espero que esto ayude.