केवल क्रमांकन के दौरान @JsonIgnore का उपयोग करना, लेकिन deserialization नहीं


325

मेरे पास एक उपयोगकर्ता ऑब्जेक्ट है जो सर्वर से और को भेजा जाता है। जब मैं उपयोगकर्ता ऑब्जेक्ट को भेजता हूं, तो मैं क्लाइंट को हैशेड पासवर्ड नहीं भेजना चाहता। इसलिए, मैंने @JsonIgnoreपासवर्ड प्रॉपर्टी पर जोड़ा , लेकिन यह इसे पासवर्ड में डिसेररलाइज्ड होने से भी रोकता है, जिससे यूजर्स को साइन इन करने में मुश्किल होती है, जब उन्हें पासवर्ड नहीं मिला।

मैं केवल @JsonIgnoreक्रमांकन पर लागू करने के लिए कैसे प्राप्त कर सकता हूं और deserialization नहीं? मैं स्प्रिंग JSONView का उपयोग कर रहा हूं, इसलिए मेरे पास एक टन का नियंत्रण नहीं है ObjectMapper

चीजें जो मैंने कोशिश की हैं:

  1. @JsonIgnoreसंपत्ति में जोड़ें
  2. @JsonIgnoreकेवल गेटर विधि पर जोड़ें

जवाबों:


481

वास्तव में ऐसा करने का तरीका जैक्सन के संस्करण पर निर्भर करता है जिसका आप उपयोग कर रहे हैं। यह संस्करण 1.9 के आसपास बदल गया , इससे पहले, आप @JsonIgnoreगेटर में जोड़कर ऐसा कर सकते थे।

जो आपने आजमाया है:

केवल गेटर विधि पर @JsonIgnore जोड़ें

ऐसा करें, और@JsonProperty अपने JSON "पासवर्ड" फ़ील्ड नाम के लिए अपनी ऑब्जेक्ट पर पासवर्ड के लिए सेटर विधि के लिए एक विशिष्ट एनोटेशन भी जोड़ें ।

जैक्सन के हाल के संस्करणों ने इसके लिए READ_ONLYऔर WRITE_ONLYएनोटेशन तर्क जोड़े हैं JsonProperty। तो आप भी कुछ ऐसा कर सकते हैं:

@JsonProperty(access = Access.WRITE_ONLY)
private String password;

डॉक्स यहां देखे जा सकते हैं


2
gist.github.com/thurloat/2510887 जैक्सन JSON के लिए पर ध्यान न दें deserialize केवल
Hadas

1
AFAIK आपको अभी भी सेटर को लागू करना है और इसे एनोटेट करना है। मैं सिर्फ़ सीरियलाइज़ेशन के लिए गेटवे चाहता हूं। आप किस क्षणिक बात करते हैं? यह एक जेपीए एनोटेशन AFAIK है
मैट ब्रोखुइस

3
इसके अलावा, क्षेत्र से @JsonProperty को स्वयं निकालना सुनिश्चित करें अन्यथा यह आपके
गेटटर

15
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
मिखाइल बैटसर

1
जैक्सन-एनोटेशन 2.5 में बाद की सुविधा नहीं है। जैक्सन-एनोटेशन 2.6.3 करता है
radiantRazor

98

इसे पूरा करने के लिए, हमें जो कुछ भी चाहिए वह है दो एनोटेशन:

  1. @JsonIgnore
  2. @JsonProperty

@JsonIgnoreकक्षा के सदस्य और उसके गेटटर और @JsonPropertyउसके सेटर पर उपयोग करें । एक नमूना चित्रण ऐसा करने में मदद करेगा:

class User {

    // More fields here
    @JsonIgnore
    private String password;

    @JsonIgnore
    public String getPassword() {
        return password;
    }

    @JsonProperty
    public void setPassword(final String password) {
        this.password = password;
    }
}

2
यह एकमात्र चीज है जिसने मेरे लिए जैक्सन 2.6.4 के साथ काम किया। मैंने @JsonProperty (access = Access.WRITE_ONLY) का उपयोग करने की पूरी कोशिश की, लेकिन यह मेरे लिए काम नहीं आया।
सिरोवालडिमेयर

77

संस्करण 2.6 के बाद से com.fasterxml.jackson.annotation.JsonProperty: क्षेत्र पर एनोटेशन का उपयोग करने के लिए एक अधिक सहज तरीका है :

@JsonProperty(access = Access.WRITE_ONLY)
private String myField;

यदि कोई गेटर मौजूद है, तो भी क्षेत्र मान को क्रमांकन से बाहर रखा गया है।

जावाडॉक कहता है:

/**
 * Access setting that means that the property may only be written (set)
 * for deserialization,
 * but will not be read (get) on serialization, that is, the value of the property
 * is not included in serialization.
 */
WRITE_ONLY

मामले में आप इसे चारों ओर की जरूरत है, बस का उपयोग करें Access.READ_ONLY


1
मुझे समझ नहीं आ रहा है कि इतने अधिक उभार क्यों हैं, इस समस्या को हल करने का यह सुंदर तरीका है, एक आकर्षण की तरह काम करता है। गेट्टर, सेटर और फील्ड को एनोटेट करने की कोई आवश्यकता नहीं है। केवल क्षेत्र। धन्यवाद।
CROSP

यह संस्करण 2.6 के बाद से उपलब्ध है, देखें fastxml.github.io/jackson-annotations/javadoc/2.6/com/…
डैनियल बीयर

शायद 2.6+ उपयोगकर्ताओं के लिए सबसे अच्छा जवाब।
डेविड डॉसॉट

सुनिश्चित करें कि आप org.codehaus.jackson.annotate आयात का उपयोग नहीं कर रहे हैं । @ जैक्सन 2.6.3 के लिए डैनियलबीर का समाधान काम करता है। यह अब स्वीकार किया जाना चाहिए कि जैक्सन को अपडेट किया गया है।
कैंट बुल

13

मेरे मामले में, मेरे पास जैक्सन स्वचालित रूप से (डी) उन वस्तुओं को क्रमबद्ध करता है जिन्हें मैं स्प्रिंग एमवीसी नियंत्रक से वापस करता हूं (मैं वसंत 4.1.6 के साथ @RestController का उपयोग कर रहा हूं)। मुझे com.fasterxml.jackson.annotation.JsonIgnoreइसके बजाय उपयोग करना था org.codehaus.jackson.annotate.JsonIgnore, अन्यथा, यह बस कुछ नहीं करता था।


1
यह एक अत्यंत उपयोगी उत्तर है जिसने वास्तव में मुझे @JsonIgnore जैक्सन द्वारा सम्मानित नहीं किया जा रहा है ... का स्रोत खोजने में मदद की ... धन्यवाद!
क्लिंट ईस्टवुड

2
"user": {
        "firstName": "Musa",
        "lastName": "Aliyev",
        "email": "klaudi2012@gmail.com",
        "passwordIn": "98989898", (or encoded version in front if we not using https)
        "country": "Azeribaijan",
        "phone": "+994707702747"
    }

@CrossOrigin(methods=RequestMethod.POST)
@RequestMapping("/public/register")
public @ResponseBody MsgKit registerNewUsert(@RequestBody User u){

        root.registerUser(u);

    return new MsgKit("registered");
}  

@Service
@Transactional
public class RootBsn {

    @Autowired UserRepository userRepo;

    public void registerUser(User u) throws Exception{

        u.setPassword(u.getPasswordIn());
        //Generate some salt and  setPassword (encoded -  salt+password)
        User u=userRepo.save(u);

        System.out.println("Registration information saved");
    }

}

    @Entity        
@JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"})
                    public class User implements Serializable {
                        private static final long serialVersionUID = 1L;

                        @Id
                        @GeneratedValue(strategy=GenerationType.AUTO)
                        private Long id;

                        private String country;

                        @Column(name="CREATED_BY")
                        private String createdBy;

                        private String email;

                        @Column(name="FIRST_NAME")
                        private String firstName;

                        @Column(name="LAST_LOGIN_DATE")
                        private Timestamp lastLoginDate;

                        @Column(name="LAST_NAME")
                        private String lastName;

                        @Column(name="MODIFICATION_DATE")
                        private Timestamp modificationDate;

                        @Column(name="MODIFIED_BY")
                        private String modifiedBy;

                        private String password;

                        @Transient
                        private String passwordIn;

                        private String phone;

                        @Column(name="RECORD_DATE")
                        private Timestamp recordDate;

                        private String salt;

                        private String status;

                        @Column(name="USER_STATUS")
                        private String userStatus;

                        public User() {
                        }
                // getters and setters
                }

4
यह भविष्य में मदद कर सकता है कि कोड कैसे काम करता है, इसका भी संक्षिप्त विवरण दें।
KWILLIAMS

ठीक है !! आप यहाँ क्या प्रयास कर रहे हैं? ज्यादा वोट मिल रहे हैं? lol
बालाजी बोगाराम रामनारायण

0

इसे संभालने का एक और आसान तरीका allowSetters=trueएनोटेशन में तर्क का उपयोग करना है । यह पासवर्ड को आपके dto में deserialized करने की अनुमति देगा, लेकिन यह ऑब्जेक्ट का उपयोग करने वाले प्रतिक्रिया बॉडी में इसे क्रमबद्ध नहीं करेगा।

उदाहरण:

@JsonIgnoreProperties(allowSetters = true, value = {"bar"})
class Pojo{
    String foo;
    String bar;
}

दोनों fooऔर barवस्तु में भर जाती है, लेकिन केवल foo एक प्रतिक्रिया शरीर में लिखा है।


यह मेरी गलती थी, मुझे नहीं पता था कि आपने स्निपेट को पहले ही ठीक कर लिया था। आपके परिवर्तनों को देखते हुए, ऐसा प्रतीत होता है कि ग्रूवी में मेरे लेखन के कुछ वर्ष मुझे मिले और जावा में मेरा अनुवाद थोड़ा कठिन था। माफ़ करना!
22
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.