2012-02-16 17 views
39

मैं एक विश्वसनीय API बना रहा हूं और जेएसओएन प्रतिक्रिया में कौन से फ़ील्ड लौटने के लिए चुनने के विकल्प के साथ डेवलपर्स प्रदान करना चाहता हूं। This blog post उदाहरण दिखाता है कि कितने एपीआई (Google, फेसबुक, लिंक्डइन) डेवलपर्स को प्रतिक्रिया को अनुकूलित करने की अनुमति देते हैं। इसे आंशिक प्रतिक्रिया के रूप में जाना जाता है।जावा का उपयोग कर आंशिक JSON प्रतिक्रिया कैसे वापस करें?

एक उदाहरण इस प्रकार दिखाई देंगे:

/users/123?fields=userId,fullname,title 

एपीआई ऊपर के उदाहरण में userId, उपयोगकर्ता "123" के लिए पूरा नाम और शीर्षक क्षेत्रों लौटना चाहिए।

मैं अपने रीस्टफुल वेब सेवा में इसे कार्यान्वित करने के विचारों की तलाश में हूं। मैं वर्तमान में सीएक्सएफ (संपादित करें: और जैक्सन) का उपयोग कर रहा हूं लेकिन एक और जेएक्स-आरएस कार्यान्वयन करने की कोशिश करता हूं।

यहां मेरे पास वर्तमान में है। यह एक पूर्ण उपयोगकर्ता वस्तु देता है। मैं केवल फ़ील्ड्स को वापस कैसे लौटा सकता हूं जो एपीआई कॉलर रनटाइम पर "फील्ड" पैरामाइटर के आधार पर चाहता है? मैं अन्य क्षेत्रों को नल बनाना नहीं चाहता हूं। मैं बस उन्हें वापस नहीं करना चाहता।

@GET 
@Path("/{userId}") 
@Produces("application/json") 
public User getUser(@PathParam("userId") Long userId, 
    @DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) { 

User user = userService.findOne(userId); 

StringTokenizer st = new StringTokenizer(fields, ","); 
while (st.hasMoreTokens()) { 

    // here's where i would like to select only the fields i want to return 

} 
return user; 
} 

अद्यतन:

मैं unludo के लिंक जो तब इस से जुड़ा हुआ पीछा किया: http://wiki.fasterxml.com/JacksonFeatureJsonFilter

कि जानकारी मैं अपने डोमेन वर्ग के लिए @JsonFilter("myFilter") जोड़ा है। तब मैं बजाय स्ट्रिंग लौट उपयोगकर्ता के लिए मेरे RESTful सेवा विधि संशोधित इस प्रकार है:

@GET 
@Path("/{userId}") 
@Produces("application/json") 
public String getUser(@PathParam("userId") Long userId, 
        @DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) { 

    User user = userService.findOne(userId); 

    StringTokenizer st = new StringTokenizer(fields, ","); 
    Set<String> filterProperties = new HashSet<String>(); 
    while (st.hasMoreTokens()) { 
     filterProperties.add(st.nextToken()); 
    } 

    ObjectMapper mapper = new ObjectMapper(); 
    FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", 
       SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties)); 

    try { 
     String json = mapper.filteredWriter(filters).writeValueAsString(user); 
     return json; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    return e.getMessage(); 
    } 
} 

मैं और अधिक परीक्षण लेकिन अब तक तो अच्छा करने की ज़रूरत है।

+0

यदि मैं फ़ील्ड क्वेरी पैरामीटर विकल्प केस असंवेदनशील बनाना चाहता हूं तो क्या होगा? –

उत्तर

17

यदि आप जैक्सन (जावा के लिए एक महान JSON lib - मानक के लिए मानक का उपयोग करते हैं) का उपयोग करते हैं, तो आप परिणामस्वरूप ऑब्जेक्ट में जो चाहते हैं उसे फ़िल्टर करने के लिए @View एनोटेशन का उपयोग कर सकते हैं।

मैं समझता हूं कि आप कुछ गतिशील चाहते हैं, इसलिए यह थोड़ा और जटिल है। आप जो खोज रहे हैं वह आपको मिलेगा: http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html (देखें 6. पूरी तरह गतिशील फ़िल्टरिंग: @JsonFilter)।

मुझे आपके द्वारा मिले समाधान में रूचि होगी।

+0

क्या होगा अगर मैं फ़ील्ड क्वेरी पैरामीटर विकल्प केस असंवेदनशील बनाना चाहता हूं? –

5

प्रत्येक अनुरोध के लिए संसाधन विधि के अंदर ऑब्जेक्ट मैपर उदाहरण बनाना महत्वपूर्ण प्रदर्शन ओवरहेड हो सकता है। the Jackson performance best practices ऑब्जेक्ट मैपर बनाने के लिए महंगे हैं।

इसके बजाय आप the Jackson 2.3 ObjectWriterModifier/ObjectReaderModifier feature का उपयोग कर संसाधन विधि के अंदर जेएक्स-आरएस प्रदाता के जैक्सन ऑब्जेक्ट लेखक को कस्टमाइज़ कर सकते हैं।

यहां एक उदाहरण दिखाया गया है कि ऑब्जेक्टवाइटर मॉडिफायर थ्रेड स्थानीय ऑब्जेक्ट को कैसे पंजीकृत किया जाए जो JAX-RS जैक्सन प्रदाता के लिए संसाधन विधि के अंदर उपयोग किए जाने वाले फ़िल्टर के सेट को बदलता है। ध्यान दें कि मैंने एक जेएक्स-आरएस कार्यान्वयन के खिलाफ कोड का परीक्षण नहीं किया है।

public class JacksonObjectWriterModifier2 { 

    private static class FilterModifier extends ObjectWriterModifier { 
     private final FilterProvider provider; 

     private FilterModifier(FilterProvider provider) { 
      this.provider = provider; 
     } 

     @Override 
     public ObjectWriter modify(EndpointConfigBase<?> endpoint, MultivaluedMap<String, Object> responseHeaders, 
            Object valueToWrite, ObjectWriter w, JsonGenerator g) throws IOException { 
      return w.with(provider); 
     } 
    } 

    @JsonFilter("filter1") 
    public static class Bean { 
     public final String field1; 
     public final String field2; 

     public Bean(String field1, String field2) { 
      this.field1 = field1; 
      this.field2 = field2; 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     Bean b = new Bean("a", "b"); 
     JacksonJsonProvider provider = new JacksonJsonProvider(); 
     ObjectWriterInjector.set(new FilterModifier(new SimpleFilterProvider().addFilter("filter1", 
       SimpleBeanPropertyFilter.filterOutAllExcept("field1")))); 

     provider.writeTo(b, Bean.class, null, null, MediaType.APPLICATION_JSON_TYPE, null, System.out); 
    } 

} 

आउटपुट:

{"field1":"a"} 
+0

क्या होगा यदि मैं फ़ील्ड क्वेरी पैरामीटर विकल्प केस असंवेदनशील बनाना चाहता हूं? –

3

लाइब्रेरी जर्सी-इकाई-फ़िल्टरिंग कि कर सकते हैं:

https://github.com/jersey/jersey/tree/2.22.2/examples/entity-filtering-selectable

https://jersey.java.net/documentation/latest/entity-filtering.html

उदाहरण:

मेरे वस्तु

public class Address { 

    private String streetAddress; 
    private String region; 
    private PhoneNumber phoneNumber; 
} 

यूआरएल

लोग/1234? चयन = streetAddress, क्षेत्र

रिटर्न

{ 
    "streetAddress": "2 square Tyson", 
    "region": "Texas" 
} 

Maven लिए उन्हें शामिल करें

<dependency> 
    <groupId>org.glassfish.jersey.ext</groupId> 
    <artifactId>jersey-entity-filtering</artifactId> 
    <version>2.22.2</version> 
</dependency> 
+0

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

+0

क्या होगा यदि मैं फ़ील्ड क्वेरी पैरामीटर विकल्प केस असंवेदनशील बनाना चाहता हूं? –

संबंधित मुद्दे