سؤال

هل من الممكن استخدام جاكسون كمسلسل/مارشالر لبيانات JSON بدلاً من JaxB عند استخدام Jersey Client API؟

إذا كان الأمر كذلك ، فكيف تكوينه؟

هل كانت مفيدة؟

المحلول

حسنًا ، لقد وجدت ذلك ، اتضح أنه بسيط للغاية بعد كل شيء:

ClientConfig cc = new DefaultClientConfig();
cc.getClasses().add(JacksonJsonProvider.class);
Client clientWithJacksonSerializer = Client.create(cc);

يأتي Jacksonjsonprovider من حزمة Jackson-Jaxrs.

نصائح أخرى

يمكنك تخطي إنشاء التكوين الخارجي وتسجيل المزود مباشرة:

Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class)

الحل مع JacksonJaxbJsonProvider

الطريقة الشائعة كيفية استخدام جاكسون مع تكوين مخصص في عميل جيرسي كانت للاستخدام JacksonJaxbJsonProvider على سبيل المثال مثل هذا

JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(yourObjectMapper());
Client client = ClientBuilder.newClient(new ClientConfig(provider));

للأسف في جيرسي 2.26 نسخوا JacksonJaxbJsonProvider فئة من com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider قطعة أثرية (جاكسون) إلى org.glassfish.jersey.media:jersey-media-json-jackson قطعة أثرية (جيرسي) وتغيير الحزمة من com.fasterxml.jackson.jaxrs.jsonإلى org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.

لا يزال من الممكن استخدام هذا النهج ، فهو ضروري فقط للتغيير JacksonJaxbJsonProvider يستورد.

بعيدا JacksonJaxbJsonProvider أن تكون الآن في internal عيب الحزمة هو أيضًا أنه يجب عليك معرفة إصدار Jersey الذي يتم تشغيل الكود الخاص بك والذي قد يمثل مشكلة عندما تتطلب تبعيات مختلفة إصدارات قميص مختلفة.

حل أفضل مع ContextResolver<ObjectMapper>

احتمال أفضل كيفية تكوين جاكسون في جيرسي عميل هو استخدام بنفس الطريقة التي يتم تكوينها في جيرسي الخادم الذي يخلق ObjectMapper مزود مثل هذا:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper = yourObjectMapper();

    @Override
    public ObjectMapper getContext(Class<?> objectType) {
        return objectMapper;
    }

}

واستخدامه على سبيل المثال مثل هذا:

ClientConfig clientConfig = new ClientConfig();
clientConfig.register(JacksonFeature.class);  // usually auto-discovered
clientConfig.register(new ObjectMapperProvider());
Client client = ClientBuilder.newClient(clientConfig);

إذا كان لديك كل من الخادم والعميل ، فيمكنك إعادة استخدامه ObjectMapperProvider صف دراسي.

يبدو أن هذا النهج يعمل من جيرسي الإصدار 2.9.

قد ترغب أيضًا في المحاولة org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider (jackson-jaxrs 1.6.1).

واجهت قضية مماثلة ، لكن بالنسبة لي لم تعمل أي من الاقتراحات المقدمة هنا. ما نجح بالنسبة لي كان أدناه قطعة من الكود:

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
...

ClientBuilder clientBuilder = ClientBuilder.newBuilder()
clientBuilder.register(JacksonFeature.class);
...
Client client = clientBuilder.build();

كان التغيير الرئيسي هو استخدام JacksonFeature.class - انها تاتي من jersey-media-json-jackson-x.yy.jar

لدي فكرة لاستخدام هذا الحل من هذه المقالة - http://www.baeldung.com/jersey-jax-rs-client

لجيرسي 2.22.2 وجاكسون 2.7.2 تبعيات Gradle هي:

dependencies {
    compile("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.7.2")
    compile("org.glassfish.jersey.core:jersey-client:2.22.2")
}

نموذج رمز العميل هو:

final String    name    = "world";
final Client    client  = ClientBuilder.newClient().register(JacksonJaxbJsonProvider.class);
final WebTarget target  = client.target("http://localhost:8080").path("hello").path(name);
final Message   message = target.request().get(Message.class);

System.out.println(message.getWelcomeMessage()); // hello world
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top