باستخدام Jackson كـ Jersey Client Serializer
سؤال
هل من الممكن استخدام جاكسون كمسلسل/مارشالر لبيانات 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