जैक्सन ObjectMapper - ऑब्जेक्ट गुणों के क्रमांकन क्रम को निर्दिष्ट करें


84

मैं एक RESTful वेब सेवा लागू कर रहा हूं, जहां उपयोगकर्ता को अनुरोध के साथ एक हस्ताक्षरित सत्यापन टोकन भेजना होगा ताकि मैं यह सुनिश्चित कर सकूं कि अनुरोध किसी मध्य व्यक्ति द्वारा छेड़छाड़ नहीं किया गया है। मेरा वर्तमान कार्यान्वयन इस प्रकार है।

सत्यापन टोकन एक VerifData वस्तु है जिसे एक स्ट्रिंग में क्रमबद्ध किया गया है और फिर हैशेड और एन्क्रिप्ट किया गया है।

class VerifData {
    int prop1;
    int prop2;
}

अपनी सेवा में, मैंने वेरिफ़डाटा के उदाहरण में क्रमबद्ध होने के लिए डेटा डाला और फिर इसे जैक्सन ऑब्जेक्टमैपर का उपयोग करके क्रमबद्ध किया और सत्यापन टोकन के साथ सत्यापन इंजन के साथ पारित किया।

VerfiData verifData = new VerifData(12345, 67890);
ObjectMapper mapper = new ObjectMapper();
String verifCodeGenerated = mapper.writeValueAsString(verifData);

लेकिन ऐसा लगता है कि हर बार एप्लिकेशन कंटेनर शुरू होने पर, ObjectMapper द्वारा गुणों के क्रम को स्ट्रिंग में मैप किया जाता है।

Ex: एक बार यह होगा

{"prop1":12345,"prop2":67890}

और दूसरी बार यह होगा

{"prop2":67890,"prop1":12345}

इसलिए यदि क्लाइंट ने पहले स्ट्रींग के रूप में वेरिफडाटा उदाहरण को क्रमबद्ध किया है, तो इसके सही होने के बावजूद इसके विफल होने की 50% संभावना है।

क्या इस से निकाल पाने के लिए कोई तरीका है? क्या मैं ObjectMapper द्वारा मानचित्रण के लिए गुणों का क्रम निर्दिष्ट कर सकता हूं (जैसे आरोही क्रम में)? या इस सत्यापन कदम को सर्वोत्तम रूप से लागू करने का कोई अन्य तरीका है। क्लाइंट और सर्वर कार्यान्वयन दोनों मेरे द्वारा विकसित किए गए हैं। मैं हस्ताक्षर और सत्यापन के लिए जावा सुरक्षा एपीआई का उपयोग करता हूं।

जवाबों:


82

से जैक्सन एनोटेशन प्रलेखन :

// ensure that "id" and "name" are output before other properties
@JsonPropertyOrder({ "id", "name" })

// order any properties that don't have explicit setting using alphabetic order
@JsonPropertyOrder(alphabetic=true)

लिंक से "सभी कोडहॉस सेवाओं को समाप्त कर दिया गया है"
एंड्रयू नॉर्मन

2
जैसा कि नीचे उल्लेख किया गया है, यदि आपका लक्ष्य किसी विशिष्ट वस्तु को क्रमबद्ध करने के बजाय हर जगह आदेश को लागू करना है, तो stackoverflow.com/a/46267506/2089674 देखें ।
user2089674

91

एनोटेशन उपयोगी होते हैं, लेकिन हर जगह लागू करने के लिए दर्द हो सकता है। आप इस तरह से काम करने के लिए अपने पूरे ObjectMapper को कॉन्फ़िगर कर सकते हैं

वर्तमान जैक्सन संस्करण: objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)

पुराने जैक्सन संस्करण: objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);


यह बिल्कुल सही नहीं है (या कम से कम सभी परिदृश्यों में काम नहीं करता है) - कुछ काम करने वाले चीज़ों के पूर्ण उदाहरण के लिए stackoverflow.com/a/46267506/2089674 देखें ।
user2089674

2
@ user2089674 - आपका उदाहरण केवल मानचित्र कुंजी के लिए काम करता है। ओपी ने वस्तु क्षेत्रों के लिए एक समाधान का अनुरोध किया।
डेव

10

जैक्सन में 2.x, जिसे आप शायद आज उपयोग कर रहे हैं, उपयोग करें:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

यदि आप लुक की परवाह करते हैं, तो आप इस पर भी विचार कर सकते हैं SerializationFeature.INDENT_OUTPUT

ध्यान दें कि इसके लिए आपको मानचित्र या ऑब्जेक्ट को क्रमबद्ध रूप से क्रमबद्ध करना होगा । यदि आप JsonNodeउदाहरण के लिए (से readTree) क्रमबद्ध करते हैं , तो यह ठीक से इंडेंट नहीं किया जाएगा।

उदाहरण

import com.fasterxml.jackson.databind.*;

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

String input = "{\"hello\": {\"cruel\" : \"world\"} }";
Object pojo = mapper.readValue(input, Object.class);
System.out.println(mapper.writeValueAsString(pojo));

का परिणाम:

{
  "hello" : {
    "cruel" : "world"
  }
}

6
केवल एक नक्शा प्रविष्टि है। इसलिए मैं यह नहीं देख सकता कि यह आदेश है।
बेन

9

स्प्रिंग बूट में आप अपने Applicationप्रवेश बिंदु वर्ग में निम्न जोड़कर इस व्यवहार को विश्व स्तर पर शामिल कर सकते हैं :

  @Bean
  public Jackson2ObjectMapperBuilder objectMapperBuilder() {

    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.featuresToEnable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

    return builder;
  }

9

एक संपत्ति निर्दिष्ट करके स्प्रिंग बूट में एक आसान तरीका है ( application.propertiesउदाहरण के लिए:

spring.jackson.mapper.sort_properties_alphabetically=true

7

निम्नलिखित 2 ObjectMapper कॉन्फ़िगरेशन की आवश्यकता है:

ObjectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
या
ObjectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)

POJO फ़ील्ड के लिए उपयोग किए जाने वाले गुण क्रमबद्धता क्रम को परिभाषित करता है
नोट : क्रमांकन पर लागू नहीं होता है java.util.Map!

तथा

ObjectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
या
ObjectMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)

फ़ीचर निर्धारित करता है कि चाहे java.util.Mapप्रविष्टियों पहले हल कर रहे हैं कुंजी के द्वारा क्रमबद्धता से पहले


स्प्रिंग बूट कॉन्फिग उदाहरण (yaml):

spring:
  jackson:
    mapper:
      SORT_PROPERTIES_ALPHABETICALLY: true
    serialization:
      ORDER_MAP_ENTRIES_BY_KEYS: true

3

डंकन मैकग्रेगर के उत्तर से: इसका इस तरह उपयोग करना बेहतर है:

objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

MapperFeature एक्सएमएल के लिए है और जैकसन-डेटाबाइंड के साथ आता है, जिसकी आवश्यकता नहीं है ...


0

ध्वज वाद का उपयोग करने के बजाय:

objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

0

आप मिक्स-इन का उपयोग कर सकते हैं और अपनी पसंद के अनुसार गुणों का क्रम निर्दिष्ट कर सकते हैं:

import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public final class ObjectMapperUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.addMixIn(Object.class, IdFirst.class);
    }

    @Bean
    public ObjectMapper objectMapper() {
        return MAPPER;
    }

    @JsonPropertyOrder({"id", "...", "..."})
    private abstract static class IdFirst {}

}

0

मुझे लगता है कि यह एक पुराना धागा है, लेकिन चूंकि मैं देख रहा था या एक उत्तर था और यहां उतरा, कुछ अतिरिक्त जानकारी अन्य लोगों के लिए उपयोगी हो सकती है।
@JsonProperty एनोटेशन मैं वर्तमान में उपयोग कर रहा हूं (जैकसन-एनोटेशन-2.11.2) "मूल्य" तर्क, एक "इंडेक्स" (संख्यात्मक) तर्क के अलावा स्वीकार करता है जो क्रमबद्धता के दौरान फ़ील्ड के आदेश को निर्दिष्ट करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.