2015-01-29 11 views
12

में HTTP शीर्षलेख पढ़ना मैं स्प्रिंग आधारित आरईएसटी एपीआई में HTTP शीर्षलेख पढ़ने की कोशिश कर रहा हूं। मैंने this का पालन किया। लेकिन मुझे यह त्रुटि मिल रही है:स्प्रिंग आरईएसटी नियंत्रक

No message body reader has been found for class java.lang.String,
ContentType: application/octet-stream

मैं जावा और वसंत में नया हूं इसलिए इसे समझ नहीं सकता।

@WebService(serviceName = "common") 
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public interface CommonApiService { 

    @GET 
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
    @Produces(MediaType.APPLICATION_JSON) 
    @Path("/data") 
    public ResponseEntity<Data> getData(@RequestHeader(value="User-Agent") String userAgent, @DefaultValue ("") @QueryParam("ID") String id); 
} 

मैं @Context की कोशिश की है: HTTPHeader इस मामले में null है

यह कैसे मेरे कॉल लग रहा है की तरह है।

HTTP शीर्षलेख से मूल्य कैसे प्राप्त करें?

+0

आपका वास्तविक अनुरोध 'एप्लिकेशन/ऑक्टेट-स्ट्रीम' के माध्यम से भेजा जा रहा है, जो वसंत एक स्ट्रिंग डेटा प्रकार पर वापस deserialize नहीं कर सकता है। इसे 'एप्लिकेशन/जेसन' (यदि आपके पास क्लासपाथ पर जैक्सन है) या जो कुछ भी आप उपभोग करने की उम्मीद कर रहे हैं उसे सेट करें और आप कहीं और प्राप्त करने में सक्षम हो सकते हैं। क्या आप किसी भी मौके से अपने आरईएसटी नियंत्रक को फाइल अपलोड करने का प्रयास कर रहे हैं? – JamesENL

+0

मैं कॉल करने के लिए Google पोस्टमैन का उपयोग कर रहा हूं। मैंने सामग्री प्रकार को एप्लिकेशन/जेसन पर सेट किया है और अभी भी त्रुटि प्राप्त कर रहा है। –

उत्तर

31

आपको जो त्रुटि मिलती है वह RequestHeader से संबंधित प्रतीत नहीं होती है।

और तुम लगते JAX-RS साथ स्प्रिंग बाकी सेवाओं भ्रमित करने के लिए, अपने विधि हस्ताक्षर होना चाहिए की तरह कुछ:

@Controller 
@RequestMapping("/rest/") 


के बारे में:

@RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "data") 
@ResponseBody 
public ResponseEntity<Data> getData(@RequestHeader(value="User-Agent") String userAgent, @RequestParam(value = "ID", defaultValue = "") String id) { 
    // your code goes here 
} 

और अपने बाकी वर्ग जैसे एनोटेशन होना चाहिए वास्तविक प्रश्न, HTTP शीर्षलेख प्राप्त करने का एक और तरीका HttpServletRequest को अपनी विधि में डालना है और फिर वांछित शीर्षलेख प्राप्त करना है।

उदाहरण:

@RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "data") 
@ResponseBody 
public ResponseEntity<Data> getData(HttpServletRequest request, @RequestParam(value = "ID", defaultValue = "") String id) { 
    String userAgent = request.getHeader("user-agent"); 
} 

के इंजेक्शन के बारे में चिंता मत करो HttpServletRequest क्योंकि वसंत आप के लिए है कि जादू करता है;)

+0

प्रश्न अद्यतन किया गया। –

+0

आप अभी भी ढांचे को मिश्रित कर रहे हैं, आप जाक्स-आरएस और वसंत आराम का उपयोग करने की कोशिश कर रहे हैं। वसंत आराम एपीआई का उपयोग करने के लिए देखो और मेरा और @ जेम्स मैस्सी उत्तर दें। –

5

मैं तुम्हें मैं कैसे का एक उदाहरण देने के लिए जा रहा हूँ मेरे नियंत्रकों के लिए आरईएसटी हेडर पढ़ें। मेरे नियंत्रक केवल अनुरोध प्रकार के रूप में एप्लिकेशन/जेसन स्वीकार करते हैं यदि मेरे पास डेटा है जिसे पढ़ने की आवश्यकता है। मुझे संदेह है कि आपकी समस्या यह है कि आपके पास एक एप्लिकेशन/ऑक्टेट-स्ट्रीम है जो वसंत को नहीं जानता कि कैसे संभालना है।

आम तौर पर मेरी नियंत्रकों इस तरह दिखेगा:

@Controller 
public class FooController { 
    @Autowired 
    private DataService dataService; 

    @RequestMapping(value="/foo/", method = RequestMethod.GET) 
    @ResponseBody 
    public ResponseEntity<Data> getData(@RequestHeader String dataId){ 
     return ResponseEntity.newInstance(dataService.getData(dataId); 
    } 

अब यहाँ पृष्ठभूमि में काम करना तो मैं यह आप के लिए नीचे टूट जाएगा कोड का एक बहुत कुछ है।

ResponseEntity एक कस्टम ऑब्जेक्ट है जो प्रत्येक नियंत्रक लौटाता है। इसमें एक स्थिर कारखाना शामिल है जो नए उदाहरणों के निर्माण की इजाजत देता है। मेरी डेटा सेवा एक मानक सेवा वर्ग है।

जादू दृश्यों के पीछे होता है, क्योंकि आप जेएसओएन के साथ काम कर रहे हैं, आपको स्प्रिंग को जैक्सन का उपयोग करने के लिए एचटीपीआरक्वेट ऑब्जेक्ट्स को मैप करने के लिए कहने की ज़रूरत है ताकि यह जान सके कि आप किसके साथ काम कर रहे हैं।

आप अपने config

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper" ref="objectMapper" /> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

ObjectMapper के अपने <mvc:annotation-driven> ब्लॉक के अंदर इस निर्दिष्ट करने के द्वारा यह कर बस com.fasterxml.jackson.databind.ObjectMapper का एक विस्तार है और क्या जैक्सन वास्तव में एक वस्तु में JSON से आपके अनुरोध मैप करने के लिए उपयोग करता है।

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

तो मेरा नियंत्रक जो मेरे नियंत्रक को भेजा जाता है, ऐसा लगता है कि इस तरह कुछ ऐसा है जो dataId नामक एक अतिरिक्त शीर्षलेख है।

आप एक अनुरोध पैरामीटर के लिए है कि बदल सकते हैं और @RequestParam String dataId का उपयोग अनुरोध से बाहर आईडी को पढ़ने के लिए करने के लिए आपके अनुरोध कुछ ऐसा दिखाई चाहते थे, तो:

contactId : {"fooId"} 

यह अनुरोध पैरामीटर के रूप में जटिल आप की तरह के रूप में किया जा सकता है । आप जेएसओएन में एक संपूर्ण ऑब्जेक्ट को क्रमबद्ध कर सकते हैं, इसे एक अनुरोध पैरामीटर के रूप में भेज सकते हैं और वसंत इसे उपयोग करने के लिए तैयार जावा ऑब्जेक्ट में वापस जैक्सन का उपयोग करके (जैक्सन का उपयोग करके) क्रमबद्ध करेगा।

उदाहरण नियंत्रक में:

@RequestMapping(value = "/penguin Details/", method = RequestMethod.GET) 
@ResponseBody 
public DataProcessingResponseDTO<Pengin> getPenguinDetailsFromList(
     @RequestParam DataProcessingRequestDTO jsonPenguinRequestDTO) 

अनुरोध प्रेषित:

jsonPengiunRequestDTO: { 
    "draw": 1, 
    "columns": [ 
     { 
      "data": { 
       "_": "toAddress", 
       "header": "toAddress" 
      }, 
      "name": "toAddress", 
      "searchable": true, 
      "orderable": true, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     }, 
     { 
      "data": { 
       "_": "fromAddress", 
       "header": "fromAddress" 
      }, 
      "name": "fromAddress", 
      "searchable": true, 
      "orderable": true, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     }, 
     { 
      "data": { 
       "_": "customerCampaignId", 
       "header": "customerCampaignId" 
      }, 
      "name": "customerCampaignId", 
      "searchable": true, 
      "orderable": true, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     }, 
     { 
      "data": { 
       "_": "penguinId", 
       "header": "penguinId" 
      }, 
      "name": "penguinId", 
      "searchable": false, 
      "orderable": true, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     }, 
     { 
      "data": { 
       "_": "validpenguin", 
       "header": "validpenguin" 
      }, 
      "name": "validpenguin", 
      "searchable": true, 
      "orderable": true, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     }, 
     { 
      "data": { 
       "_": "", 
       "header": "" 
      }, 
      "name": "", 
      "searchable": false, 
      "orderable": false, 
      "search": { 
       "value": "", 
       "regex": false 
      } 
     } 
    ], 
    "order": [ 
     { 
      "column": 0, 
      "dir": "asc" 
     } 
    ], 
    "start": 0, 
    "length": 10, 
    "search": { 
     "value": "", 
     "regex": false 
    }, 
    "objectId": "30" 
} 

जो स्वत: नियंत्रक मुझे इस्तेमाल करने के लिए तैयार करने के लिए दिए जाने से पहले एक DataProcessingRequestDTO वस्तु में वापस धारावाहिक हो जाता है।

जैसा कि आप देख सकते हैं, यह बहुत शक्तिशाली है जिससे आप JSON से अपने डेटा को कोड की एक पंक्ति लिखने के बिना किसी ऑब्जेक्ट को क्रमबद्ध कर सकते हैं। आप @RequestParam और @RequestBody के लिए ऐसा कर सकते हैं जो आपको अपने पैरामीटर के अंदर JSON तक पहुंचने या क्रमशः अनुरोध करने की अनुमति देता है।

अब आपके पास जाने के लिए एक ठोस उदाहरण है, तो आपको अपना अनुरोध प्रकार application/json पर बदलने के बाद आपको कोई समस्या नहीं होनी चाहिए।

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