【问题标题】:force glassfish 4 to use jackson 2.3强制 glassfish 4 使用 jackson 2.3
【发布时间】:2014-01-09 16:22:06
【问题描述】:

我编写了一个应该在 Glassfish 4 上运行的 maven 应用程序。

标准 ApplicationConfig 如下所示:

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

现在的问题是,我生成 Json 的资源应该使用 jackson 2.3 注释。 但是我的 glassfish 使用了一些 codehaus。 ... 提供 json 的包。 codehaus 是杰克逊的旧版本。我想使用提供@JsonIdentityInfo 注释的fastxml 中的新版本。

我认为我可以通过写作来解决我的问题:

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

但是没有效果。现在 Glassfish 使用标准的 JsonProvider Moxy... 我不想使用。你有什么提示我可以强制 glassfish 使用我的库而不是内置库吗?或者我可以将内置库更改为较新的库吗?


如果你知道如何解决这个问题。能否请您提供一点代码-sn-p?


编辑 1:


尝试第一种方法解决后:

新的应用程序配置:

@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.
    }

}

杰克逊特点:

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>

依赖关系:

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

错误:

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)
    ...

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>>)]

编辑 2:

我现在将发布我项目的一些课程。在那个类中,我包含了我使用的所有注释。

我有 16 个这样的实体:

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.
}

然后我有很多这样的 DAO:

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

最后我有很多这样的资源:

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

}

这是第一部分。作为第二部分,我有一些谷歌服务的课程。因为我想尝试使用一些谷歌地理位置和路由。我将 Google-Code 放入 pasteBin 文件,因为它太大了:

http://pastebin.com/u3e0dms6

我使用的库如下:

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;

我希望这会有所帮助。所有其他类都使用相同的注解。

【问题讨论】:

  • 我将“jackson.jaxrs.base”添加到我的依赖项中,现在我得到另一个焊接错误。 WELD-001408 类型 [IterableProvider>] 的依赖项不满足

标签: glassfish jersey jackson jax-rs java-ee-7


【解决方案1】:

首先确保您的 pom.xml 中有以下内容:

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

然后确保你在任何 pom.xml 中都没有这个:

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

然后你需要禁用moxy。最简单的方法是放弃您的 Application 类并替换为 ResourceConfig 类。首先让我们创建您的 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;
        }
    }

这里有两件有趣的事情,首先我禁用了 moxy,其次我确保添加了 JacksonException 映射器。这样,如果存在解析或生成异常,您将获得比内部服务器错误更好的错误。好的,最后一步,将您的应用程序重写为 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 );
    }
}

应该这样做。另外,不用像这样一个一个地注册资源,如果你知道它们的路径,你可以删除所有代码并将其添加到 RestApplication 的构造函数中:

package( "com.me.myrestresourcespackage" );

希望这会有所帮助。

【讨论】:

  • 嗨,我已经在网上阅读过这种解决方案。我想这也是你的;-)。所以我会再试一次。您可以在上面的原始帖子中阅读我第二次尝试的结果。当我尝试您的解决方案时,我遇到了一些依赖项的问题。你知道我怎么解决这个问题吗?我读到这可能是因为番石榴。
  • 您必须添加具有注释的代码,以便我们可以看到它。
  • 感谢您的宝贵时间。我希望我们能解决这个问题:-)
  • 好的,现在这是 CDI 和 HK2 的问题,而不是 Jackson 和 Jersey 的问题。看看这个问题和答案。 stackoverflow.com/questions/17224270/…
  • JsonParseExceptionMapper 被声明为已弃用:(
猜你喜欢
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多