كيفية إعادة استخدام جيرسي JSON / JAXB عن التسلسل؟

StackOverflow https://stackoverflow.com/questions/1071749

  •  21-08-2019
  •  | 
  •  

سؤال

ولدي خدمة REST JAX-RS نفذت باستخدام جيرسي. واحدة من الميزات الرائعة من JAX-RS / جيرسي هي الطريقة التي يمكن بسهولة أن تتحول إلى POJO في خدمة REST، ببساطة عن طريق رش بعض الشروح جافا ... بما في ذلك آلية سهلة مسلي للترجمة POJOs إلى JSON - استخدام التعليقات JAXB

والآن، أود أن تكون قادرة على الاستفادة من هذه الوظيفة باردة-ifying JSON لأغراض غير REST - أحب أن تكون قادرة على إجراء تسلسل فقط بعض من هذه الكائنات إلى القرص، كما نص JSON. وإليك مثالا الكائن JAXB ان كنت تريد تسلسل:

@XmlRootElement(name = "user")
public class UserInfoImpl implements UserInfo {

    public UserInfoImpl() {} 

    public UserInfoImpl(String user, String details) {
        this.user = user;
        this.details = details;
    }

    public String getUser() { return user; }
    public void setUser(String user) { this.user = user; }

    public String getDetails() { return details; }
    public void setDetails(String details) { this.details = details; }

    private String user;
    private String details;
}

وجيرسي يمكن أن تتحول إلى واحدة من هذه سلمان مع أي معلومات إضافية. أنا أتساءل إذا جيرسي كشفت هذه الوظيفة في API لتلبية احتياجات مثل الألغام؟ لقد كان لا حظ العثور عليه حتى الآن ...

وشكرا!

<القوي> UPDATE 2009-07-09 : في تعلمته التي يمكن استخدامها يعترض على مقدمي إلى <م> تقريبا تفعل بالضبط ما أريد:

  @Context Providers ps;
  MessageBodyWriter uw = ps.getMessageBodyWriter(UserInfoImpl.class, UserInfoImpl.class, new Annotation[0], MediaType.APPLICATION_JSON_TYPE);

  uw.writeTo(....)

... هذا يكتب الكائن كما سلمان إلى أي outputstream، الذي سيكون مثاليا بالنسبة لي، ولكن لا يسعني إلا أن الحصول على مقدمي الكائن باستخدامcontext من كائنComponent. لا أحد يعرف كيفية الوصول إليه من العادية، POJO-المشروح الامم المتحدة؟ شكرا!

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

المحلول

يستخدم

وجيرسي بضعة أطر مختلفة اعتمادا على ما إذا كنت تستخدم معين ()، badgerfish ()، أو طبيعي) تدوين (. الطبيعي هو عادة واحدة من الناس يريدون. وهذا ما نفذت باستخدام جيد جدا (وسريع جدا) مستقل جاكسون JSON المعالج، وأعتقد، والذي يذهب من Object-> JAXB-> JSON. ومع ذلك يوفر جاكسون أيضا هو نفسه مزود JAX-RS للذهاب مباشرة Object-> JSON.

في الواقع، انهم حتى واضاف لدعم الشروح JAXB. إلقاء نظرة على

http://wiki.fasterxml.com/JacksonJAXBAnnotations

وأعتقد أن هذا هو في نهاية المطاف ما كنت تبحث عنه. جاكسون لم كائن <-> معالجة JSON ... جيرسي فقط يجعل المكالمات بالنسبة لك

نصائح أخرى

وفيما يلي مثال مختصر بسيط لاستخدام JAXB لتعيين الكائنات إلى JSON (باستخدام جاكسون):

http://ondra.zizka.cz/ stranky / programovani / جافا / JAXB-سلمان-جاكسون-howto.texy

ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(pojoObject);

والشروح JAXB تعمل بشكل جيد عندما تسلسل إلى XML. المشكلة الرئيسية هي أن JAXB لا يدعم صفوف فارغة. لذلك عندما تسلسل شيء من هذا القبيل ...

List myArray = new ArrayList();

... لJSON عبر anottations JAXB كل ما تبذلونه من صفائف فارغة تصبح لاغية بدلا من [].

لحل هذه يمكنك فقط تسلسل pojos مباشرة إلى سلمان عبر جاكسون.

ونلقي نظرة على هذا من دليل المستخدم جيرسي: http://jersey.java.net/nonav/documentation/latest /user-guide.html#d0e1959

وهذه هي أفضل طريقة لاستخدام مزود جاكسون دون JAXB. وعلاوة على ذلك، يمكنك دائما استخدام أحدث نسخة من جاكسون قبل downlaoding جاكسون-كل x.y.z جرة من على شبكة الإنترنت.

وهذه الطريقة سوف لا تتداخل مع الشروح JAXB بحيث أود أن أقترح لديها في محاولة!

ومنذ جيرسي هو تطبيق إشارة من JAX-RS وJAX-RS تركز تماما على توفير وسيلة معيارية للتنفيذ نقطة النهاية لخدمة REST يتم ترك قضايا تسلسل الحمولة إلى غيرها من المعايير.

وأعتقد أنه إذا كانت تضم التسلسل الكائن في JAX-RS معيار أنها ستصبح بسرعة كبيرة برئاسة متعددة الوحش الذي سيكون من الصعب تنفيذ وتفقد بعض من التركيز انها.

وأنا أقدر كيف تركز جيرسي على تقديم نظيفة وسهلة الاستعمال النهاية REST. في حالتي أنا كنت subclassed فقط أحد الوالدين أن لديه كل السباكة JAXB في ذلك الأجسام التنظيم حتى بين ثنائي وXML نظيفة جدا.

ومع قليل من جيرسي إلباس الحذاء معين، يمكنك استخدامه لإنشاء كائنات JSON من الضروري بالنسبة لك. تحتاج إلى تضمين التبعيات التالية (يمكنك استخدام حزمة، لكنه لن يسبب مشاكل إذا كنت تستخدم لحام للاختبار):

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.12</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.12</version>
    </dependency>

ومن هناك يمكنك إنشاء فئة JAXB المشروح. وفيما يلي مثال:

@XmlRootElement
public class TextMessage {
private String text;
    public String getText() { return text; }
    public void setText(String s) { this.text = text; }
}

وبعد ذلك يمكنك إنشاء وحدة اختبار التالية:

    TextMessage textMessage = new TextMessage();
    textMessage.setText("hello");
    textMessage.setUuid(UUID.randomUUID());

    // Jersey specific start
    final Providers ps = new Client().getProviders();
    // Jersey specific end
    final MultivaluedMap<String, Object> responseHeaders = new MultivaluedMap<String, Object>() {

        @Override
        public void add(final String key, final Object value) {
        }

        @Override
        public void clear() {
        }

        @Override
        public boolean containsKey(final Object key) {
            return false;
        }

        @Override
        public boolean containsValue(final Object value) {
            return false;
        }

        @Override
        public Set<java.util.Map.Entry<String, List<Object>>> entrySet() {
            return null;
        }

        @Override
        public List<Object> get(final Object key) {
            return null;
        }

        @Override
        public Object getFirst(final String key) {
            return null;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public Set<String> keySet() {
            return null;
        }

        @Override
        public List<Object> put(final String key, final List<Object> value) {
            return null;
        }

        @Override
        public void putAll(
                final Map<? extends String, ? extends List<Object>> m) {
        }

        @Override
        public void putSingle(final String key, final Object value) {
        }

        @Override
        public List<Object> remove(final Object key) {
            return null;
        }

        @Override
        public int size() {
            return 0;
        }

        @Override
        public Collection<List<Object>> values() {
            return null;
        }
    };

    final MessageBodyWriter<TextMessage> messageBodyWriter = ps
            .getMessageBodyWriter(TextMessage.class, TextMessage.class,
                    new Annotation[0], MediaType.APPLICATION_JSON_TYPE);
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Assert.assertNotNull(messageBodyWriter);

    messageBodyWriter.writeTo(textMessage, TextMessage.class,
            TextMessage.class, new Annotation[0],
            MediaType.APPLICATION_JSON_TYPE, responseHeaders, baos);
    final String jsonString = new String(baos.toByteArray());
    Assert.assertTrue(jsonString.contains("\"text\":\"hello\""));

وميزة لهذا النهج هو أنه يبقي كل شيء داخل API JEE6، وهناك حاجة صراحة لم المكتبات الخارجية باستثناء الاختبار والحصول على مقدمي الخدمات. ومع ذلك، تحتاج إلى تهيئة تنفيذ MultivaluedMap لأنه ليس هناك شيء المنصوص عليها في المعايير، ونحن في الواقع لا يستخدمونه. أنه قد أيضا أن تكون أبطأ من GSON، والكثير أكثر تعقيدا مما هو ضروري.

وأنا أفهم وجهات النظر XML ولكن سيكون أظهرت بعض التبصر تحتاج إلى دعم JSON لPOJOs كتجهيز قياسي. الحاجة إلى الطبيب حتى معرفات JSON مع أحرف خاصة لا معنى له إذا التطبيق الخاص بك هو JSON والعميل الخاص بك هو جافا سكريبت RIA.

وأيضا، لا أن الفول جافا ليست POJOs. وأود أن استخدام شيء من هذا القبيل على السطح الخارجي من بلدي تطبيقات الويب:

public class Model
{
   @Property height;
   @Property weight;
   @Property age;
}

ولا منشئ افتراضي، لا جالبة / اضع الضوضاء، مجرد POJO مع الشروح الخاصة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top