2012-05-01 7 views
5

हम कुछ काफी बुनियादी POJO संस्थाओं के साथ JAX-आरएस उपयोग कर रहे हैं और @GET और @POST एनोटेट तरीकों कि @Produce और @ConsumeMediaType.APPLICATION_JSON, MediaType.APPLICATION_XML की एक संख्या है। कुछ भी शानदार नहीं है।जेएक्स-आरएस के साथ जेएक्सबी डेटा का व्यावहारिक सत्यापन?

प्रश्न मेरे पास है कि मैं डेटा को कितनी अच्छी तरह से मान्य कर सकता हूं?

हमारे पास एक XML स्कीमा नहीं है हालांकि मैं एक उत्पन्न कर सकता हूं। मुझे इसे किसी भी तरह से हुक करने की आवश्यकता होगी जो बहुत आकर्षक नहीं दिखता है और मुझे अभी तक एक संक्षिप्त उदाहरण नहीं मिला है।

हम "बीन सत्यापन" का उपयोग कर सकते हैं, लेकिन मैं फिर से अनिश्चित हूं कि मैं इसे कैसे हुक कर सकता हूं और इसे बुला सकता हूं।

अंत में (मुझे लगता है) हम उदाहरण के लिए पीओजेओ को कुछ isValidForXXX() विधियों को जोड़ सकते हैं और जब भी हमारे पास एक उदाहरण दिया जाता है तो उन्हें कॉल करें।

किसी को भी सिफारिशें?

उत्तर

2

यदि आपके पास एक्सएमएल स्कीमा है तो आप MessageBodyReader के अंदर जेएक्सबी सत्यापन का उपयोग कर सकते हैं। एक ठोस उदाहरण के लिए एक समान प्रश्न के लिए मेरा जवाब देखें।

ValidatingReader

नीचे MessageBodyReader कि चार काम करता है की एक नंगे हड्डियों दिया गया है: 1) Create a JAXBContext, 2) Schema का एक उदाहरण बनाएँ, 3) स्कीमा सेट Unmarshaller पर 4) Unmarshals InputStream

package org.example; 

import java.io.*; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 
import java.net.URL; 

import javax.ws.rs.*; 
import javax.ws.rs.core.*; 
import javax.ws.rs.ext.*; 
import javax.xml.XMLConstants; 
import javax.xml.bind.*; 
import javax.xml.validation.*; 

@Provider 
@Consumes("application/xml") 
public class ValidatingReader implements MessageBodyReader<Customer> { 

    @Context 
    protected Providers providers; 

    private Schema schema; 
    private JAXBContext jaxbContext; 

    public ValidatingReader() { 
     try { 
      JAXBContext jc = JAXBContext.newInstance(Customer.class); 
      SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
      URL schemaURL = null; // URL for your XML schema 
      schema = sf.newSchema(schemaURL); 
     } catch(Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) { 
     return arg0 == Customer.class; 
    } 

    public Customer readFrom(Class<Customer> arg0, Type arg1, Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5) 
      throws IOException, WebApplicationException { 
     try { 
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
      unmarshaller.setSchema(schema); 
      return (Customer) unmarshaller.unmarshal(arg5); 
     } catch(JAXBException e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 
+4

मैं वास्तव में बहुत कोड है कि ज़रूरत है मान्य होगा?वास्तव में कुछ आसान खोज रहा था ... – jmkgreen

+0

@jmkgreen - मैंने एक ठोस उदाहरण के साथ अपना जवाब अपडेट कर दिया है। –

+2

@ अभिषेक रंजन, "रनटाइम कंटेनर के साथ रजिस्टर प्रदाता कक्षाएं" कहने के लिए बेहतर है। जवाब देने के लिए आपको यह समझने की आवश्यकता है कि आप किस रनटाइम कंटेनर का उपयोग कर रहे हैं और क्या होगा यदि कोई ढांचा स्वचालित रूप से प्रदाता कक्षाओं को पढ़ रहा हो, तो उन्हें अपने कंटेनर में स्वचालित रूप से पंजीकृत न करें। – jmkgreen

0

एक MessageBodyReader उत्कृष्ट @Blaise Doughan पता चलता है के रूप में उपयोग करने से आप की बहुत अधिक देता है। जाहिर है, अगर आपके पास @ कंस्यूम एनोटेशन और आपकी जेएक्सबी-एनोटेटेड क्लास पहले से ही है, तो मैं देख सकता हूं कि यह वर्बोज़ कैसा दिखता है।

यह वास्तव में आपके आराम स्तर पर है। मुझे लगता है कि आपने एक एक्सएमएल स्कीमा को परिभाषित नहीं किया है, इसलिए आपने हाथ से अपनी जेएक्सबी कक्षाएं बनाई हैं, और यह समान वर्गों (या बाहरी कस्टम सत्यापनकर्ता) में सत्यापन तर्क को कोड करने के लिए तार्किक लगता है।

मैं व्यक्तिगत रूप से लिखने पर विचार करता हूं कि एक्सएमएल स्कीमा, खासकर अगर आपके सत्यापन नियम आसानी से व्यक्त किए जाते हैं। यह आपके प्रोजेक्ट के लिए एक अच्छा निवेश हो सकता है: आप तब से स्वचालित रूप से जेएक्सबी कक्षाएं उत्पन्न कर सकते हैं, और सत्यापन स्वचालित रूप से प्राप्त कर सकते हैं, इसलिए आपके पास बेहतर रखरखाव आगे बढ़ना चाहिए।

+1

तो अगर मैं एक्सएसडी लिखता हूं और फिर जेएक्सबी कक्षाओं को जनरेट करता हूं, तो सत्यापन स्वचालित रूप से जेएक्स-आरएस के लिए होगा? मुझे संदेशबॉडी रीडर खुद लिखने की ज़रूरत नहीं है ?? – adi

+1

यह स्वचालित रूप से नहीं होगा, लेकिन उपरोक्त संदेशबॉडी रीडर दृष्टिकोण आपका एकमात्र विकल्प नहीं है, इसके बजाय आप javax.ws.rs.ext.ContextResolver का उपयोग कर सकते हैं। उत्कृष्ट ब्लॉग पोस्ट यहां देखें: http://sleeplessinslc.blogspot.com/2011/10/jersey-jax-rs-and-jaxb-schema.html –

+0

ठीक है .. और JSON सत्यापन के बारे में क्या? – adi

1

मूल पोस्टर के समान चीज़ को पूरा करने के लिए देख रहा था। चूंकि MessageBodyReader से बचने की इच्छा प्रतीत होती है, मैंने सोचा कि मैं इस समाधान को साझा करूंगा, जो पैरामीटर के रूप में HttpServletRequest का उपयोग करता है और फिर डेटा के साथ सीधे काम करने के लिए getInputStream विधि का उपयोग करता है।

@POST 
@Path("/myPath") 
@Consumes(MediaType.APPLICATION_XML) 
public Response saveCustomerInteraction(@Context HttpServletRequest httpRequest) { 

    Response response = null; 
    try { 
     CustomerInteraction ci = this.handleCustomerInteractionRequest(httpRequest); 
     if (ci!=null){ 
      // save your data or whatever your app does 
     } 
     else { 
      response = Response.status(Status.BAD_REQUEST).entity("invalid XML").build();    
     } 
    } 
    catch(Exception e){ 
     log.error(e.getMessage(),e); 
     response = Response.serverError().entity(e.getMessage()).build(); 
    } 
    return response; 
} 

handleCustomerInteractionRequest विधि तो सर्वलेट धारा संभाल और एक्सएमएल

protected CustomerInteraction handleCustomerInteractionRequest(HttpServletRequest request){ 

    CustomerInteraction ci = null; 
    try { 
     SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     Schema schema = sf.newSchema(schemaUrl); 
     JAXBContext jaxbContext = JAXBContext.newInstance(CustomerInteraction.class); 
     Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
     unmarshaller.setSchema(schema); 
     ci = (CustomerInteraction) unmarshaller.unmarshal(request.getInputStream());  
    } 
    catch (Exception e){ 
     // log error and return a null (or whatever you want to do with the error) 
    } 

    return ci; 
} 
संबंधित मुद्दे