2012-12-07 16 views
19

मुझे प्रस्तुत करने से पहले नामों से कुछ फ़ील्ड को बाहर करने की आवश्यकता है। फ़ील्ड की सूची गतिशील है, इसलिए मैं एनोटेशन का उपयोग नहीं कर सकता।मैं जैक्सन के साथ एनोटेशन का उपयोग न करने वाले फ़ील्ड को कैसे बाहर निकालूं?

मैंने कस्टम सीरिएलाइज़र बनाने की कोशिश की है - लेकिन मुझे फील्ड नाम नहीं मिल सकता है।

जीसन I'v में ExclusionStrategy का उपयोग किया गया, लेकिन जैक्सन की ऐसी कोई कार्यक्षमता नहीं है। क्या यह?

+0

क्या आप रनटाइम पर गुणों को बाहर करने का प्रयास कर रहे हैं? उदाहरण के लिए आपके पास नक्शा है, और इसके अंदर कुछ गुणों को बाहर करना चाहते हैं? – eugen

+0

हां, लेकिन यह 'order.id' ' order.content.items' – Roman

उत्तर

24

नाम से फ़ील्ड को छोड़ने का नीचे उदाहरण my blog post, Gson v Jackson - Part 4 से है। (PropertyFilterMixIn के लिए खोजें।) यह उदाहरण FilterProvider का उपयोग SimpleBeanPropertyFilter से serializeAllExcept उपयोगकर्ता नाम फ़ील्ड नामों की एक निर्दिष्ट सूची के साथ करता है।

@JsonFilter("filter properties by name") 
class PropertyFilterMixIn {} 

class Bar 
{ 
    public String id = "42"; 
    public String name = "Fred"; 
    public String color = "blue"; 
    public Foo foo = new Foo(); 
} 

class Foo 
{ 
    public String id = "99"; 
    public String size = "big"; 
    public String height = "tall"; 
} 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.getSerializationConfig().addMixInAnnotations( 
     Object.class, PropertyFilterMixIn.class); 

    String[] ignorableFieldNames = { "id", "color" }; 
    FilterProvider filters = new SimpleFilterProvider() 
     .addFilter("filter properties by name", 
      SimpleBeanPropertyFilter.serializeAllExcept( 
       ignorableFieldNames)); 
    ObjectWriter writer = mapper.writer(filters); 

    System.out.println(writer.writeValueAsString(new Bar())); 
    // output: 
    // {"name":"James","foo":{"size":"big","height":"tall"}} 
    } 
} 

(नोट:। प्रासंगिक API हाल ही में एक जैक्सन रिलीज के साथ थोड़ा बदल गया हो)

उदाहरण एक उचित रूप में अनावश्यक एनोटेशन का उपयोग करता है, एनोटेशन क्षेत्रों बाहर रखा जाना करने के लिए लागू नहीं है। (आवश्यक विन्यास एक सा, इस मुद्दे JACKSON-274 के कार्यान्वयन के लिए वोट करने के लिए संकोच नहीं करते कृपया सरल करने के लिए बदल एपीआई प्राप्त करने में मदद करने के लिए

+1

हां, यह ठीक काम करता है, यह डॉट नोटेशन बहिष्करण होना चाहिए। धन्यवाद। लेकिन मैं अभी भी कुछ चीज़ों जैसे 'some.items' (कुछ की जड़ों के साथ वस्तुओं को छोड़कर) जटिल बहिष्करण नहीं कर सकता हूं – Roman

+4

मैं आपको वही सुविधा ढूंढ रहा हूं, जो मेरे मामले के लिए पर्याप्त नहीं है, दिए गए समाधान, क्योंकि जो भी सुझाया गया है उसका उपयोग करने से नेस्टेड ऑब्जेक्ट्स में भी उसी नाम वाले फ़ील्ड। और मैं उन्हें केवल शीर्ष स्तर पर बाहर करना चाहता हूं। इसलिए यह निर्दिष्ट करने का एक तरीका है कि संपत्ति को किन स्तर पर नजरअंदाज किया जाना चाहिए। –

+1

ठीक है अब समाधान मिला है? – StackHola

6

जैक्सन इस तरह सबसे बातों के लिए एनोटेशन पर निर्भर करता है;। लेकिन आप सीधे टिप्पणी करने की जरूरत नहीं है मूल्य वर्गों। तुम भी उपयोग कर सकते हैं "मिश्रण-में एनोटेशन" (http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html देखें)।

और फिर उसके लिए कुछ विकल्प आप से परे का उपयोग कर सकते बुनियादी @JsonIgnore (प्रति-संपत्ति) या @JsonIgnoreProperties (प्रति वर्ग), http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html देख रहे हैं

+1

मैं रनटाइम बहिष्करण के बारे में बात कर रहा हूं। मुझे अनुरोध है कि किन क्षेत्रों को बाहर निकालना है और इसे – Roman

+1

से बाहर निकालना है, फिर आपकी सबसे अच्छी शर्त है कि इसे पेड़ मॉडल का उपयोग करके स्वयं बनाना; या "JSON फ़िल्टर" लागू करें (दूसरे आलेख से)। सौभाग्य से @ {प्रोग्रामर ब्रूस} ने दिखाया कि कैसे dlatter करने के लिए। – StaxMan

+0

@ जेसन इग्नोर को गेटर विधि पर भी लागू किया जा सकता है। –

5

यदि आपके पास दो या दो से अधिक pojo पर परिभाषित फ़िल्टर हैं, तो आप इसे आजमा सकते हैं:

@JsonFilter("filterAClass") 
class AClass 
{  
    public String id = "42"; 
    public String name = "Fred"; 
    public String color = "blue"; 
    public int sal = 56; 
    public BClass bclass = new BClass(); 
} 

//@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 
@JsonFilter("filterBClass") 
class BClass 
{ 

    public String id = "99"; 
    public String size = "90"; 
    public String height = "tall"; 
    public String nulcheck =null; 
} 
public class MultipleFilterConcept { 
    public static void main(String[] args) throws Exception 
     { 
     ObjectMapper mapper = new ObjectMapper(); 
    // Exclude Null Fields 
     mapper.setSerializationInclusion(Inclusion.NON_NULL); 
     String[] ignorableFieldNames = { "id", "color" }; 
     String[] ignorableFieldNames1 = { "height","size" }; 
     FilterProvider filters = new SimpleFilterProvider() 
      .addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)) 
      .addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1)); 
     ObjectWriter writer = mapper.writer(filters); 
     System.out.println(writer.writeValueAsString(new AClass())); 

     } 
} 
9

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

लाइब्रेरी इसे समझने के लिए बहुत आसान बनाता है। यह तो आप बस यह करने के लिए अनुमति देता है:

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.module.SimpleModule; 
import com.monitorjbl.json.JsonView; 
import com.monitorjbl.json.JsonViewSerializer; 
import static com.monitorjbl.json.Match.match; 

//initialize jackson 
ObjectMapper mapper = new ObjectMapper(); 
SimpleModule module = new SimpleModule(); 
module.addSerializer(JsonView.class, new JsonViewSerializer()); 
mapper.registerModule(module); 

//get a list of the objects 
List<MyObject> list = myObjectService.list(); 

String json; 
if(user.getRole().equals('ADMIN')){ 
    json = mapper.writeValueAsString(list); 
} else { 
    json = mapper.writeValueAsString(JsonView.with(list) 
     .onClass(MyObject.class, match() 
      .exclude("*") 
      .include("name"))); 
} 

System.out.println(json); 

कोड उपलब्ध on GitHub है, आशा है कि यह मदद करता है!

2

मैंने Squiggly Filter नामक एक लाइब्रेरी लिखी, जो फेसबुक ग्राफ एपीआई सिंटैक्स के सबसेट पर आधारित फ़ील्ड का चयन करता है। उदाहरण के लिए, उपयोगकर्ता ऑब्जेक्ट के पता फ़ील्ड के ज़िप कोड का चयन करने के लिए, आप क्वेरी स्ट्रिंग ?fields=address{zipCode} का उपयोग करेंगे। Squiggly फ़िल्टर के फायदों में से एक यह है कि जब तक आप ऑब्जेक्टमैपर तक पहुंच प्राप्त करते हैं जो जेसन को प्रस्तुत करता है, तो आपको अपने किसी भी नियंत्रक विधियों के कोड को संशोधित करने की आवश्यकता नहीं है।

मान लिया जाये, तो आप सर्वलेट एपीआई का उपयोग कर रहे हैं, तो आप निम्न कर सकते हैं:

1) एक फिल्टर

<filter> 
    <filter-name>squigglyFilter</filter-name> 
    <filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>squigglyFilter</filter-name> 
    <url-pattern>/**</url-pattern> 
</filter-mapping> 

2) ObjectMapper

Squiggly.init(objectMapper, new RequestSquigglyContextProvider()); 

3 प्रारंभ रजिस्टर) आप अब आपके जेसन

curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2} 
फ़िल्टर कर सकते हैं

Squiggly फ़िल्टर पर अधिक जानकारी github पर उपलब्ध है।