मेरे पास एक ऐसा एप्लिकेशन है जो एक JSON-स्वरूपित स्ट्रिंग के रूप में PUT अनुरोधों को स्वीकार करने वाले एंडपॉइंट को उजागर करता है, उदाहरण:

PUT /my/endpoint
"some string"

मेरा समापन बिंदु विधि हस्ताक्षर कुछ इस प्रकार है:

@RequestMapping(
        path = "/my/endpoint",
        consumes = "application/vnd.mycompany.myservice-v1.hal+json"
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final String myString
) {
    ...
}

स्प्रिंग बूट 1 (1.5.22.RELEASE) का उपयोग करते हुए, ऊपर दिए गए PUT उदाहरण के लिए myString का मान शाब्दिक पाठ some string होगा, लेकिन स्प्रिंग बूट 2 (2.3.6.2) के तहत। RELEASE), अब यह शाब्दिक पाठ "some string" है - यानी ऐसा लगता है कि इनपुट को JSON के रूप में सख्ती से पार्स नहीं किया जा रहा है क्योंकि उद्धरण हटाए नहीं गए हैं।

मेरा मानना ​​है कि उद्धृत तार वैध JSON हैं (और यह कि बिना उद्धृत तार नहीं हैं), बस एक वस्तु के रूप में ({ और } में) और एक सूची ([ में) और ]) होंगे।

मैंने कुछ बाहरी विवरण निकाले हैं जो मुझे नहीं लगता कि समस्या के लिए मायने रखता है (उदाहरण के लिए हम वापसी मूल्य के रूप में CompletableFuture का उपयोग कर रहे हैं, मेरे पास वहां भी एक @PathVariable है और कुछ एनोटेशन-संचालित सत्यापन चल रहा है), लेकिन मैंने इसमें छोड़ दिया है कि हम एक कस्टम मीडिया-प्रकार का उपयोग कर रहे हैं जिसमें इसके साथ कुछ करना है।

कोई विचार है कि मैं अपने अनुरोध निकाय को JSON के रूप में ठीक से व्यवहार करने के लिए स्प्रिंग बूट 2 को कैसे मना सकता हूं? दुर्भाग्य से, मैं एपीआई को फिर से परिभाषित नहीं कर सकता क्योंकि हमारे पास पहले से ही इसका उपयोग करने वाले लाइव ग्राहक हैं।

3
AndyB 24 नवम्बर 2020, 19:10

3 जवाब

सबसे बढ़िया उत्तर

यह सबसे अच्छा विकल्प नहीं हो सकता है, लेकिन अगर शुरुआत में कुछ और मदद नहीं करता है। String के बजाय स्प्रिंग को RequestBody को Object के रूप में हैंडल करने दें। बिल्कुल वैसा ही:

public ResponseEntity<String> myEndpoint(@RequestBody final Object myString)

String का उपयोग करते समय स्प्रिंग जैक्सन का उपयोग पार्सिंग के लिए भी नहीं कर सकता है, लेकिन शरीर को String के रूप में संभालता है जिसमें शरीर के सभी वर्ण होने चाहिए, यहां तक ​​​​कि सामग्री प्रकार JSON पर सेट है।

यदि आप निम्न कार्य करते हैं:

String myString2 = new ObjectMapper().readValue(myString, String.class);

आप इसे देख सकते हैं जिसके परिणामस्वरूप myString2 आसपास के दोहरे उद्धरण चिह्न नहीं हैं।

Object के लिए वसंत इसे अलग तरह से संभालता है। यह इसे एक String बनाता है लेकिन ऐसा लगता है कि इसे JSON मान के रूप में माना जाता है (और String मान के रूप में क्योंकि आसपास के दोहरे उद्धरण हैं) इसमें आसपास के दोहरे उद्धरण नहीं होने चाहिए।

यदि आप Object का उपयोग करते हैं और फिर myString.getClass() लॉग करते हैं तो आप देखेंगे कि यह वास्तव में एक java.lang.String है।

1
pirho 24 नवम्बर 2020, 22:28

सबसे पहले जैसा कि आपने कहा था कि आप PUT कॉल कर रहे हैं तो आपको विधि स्तर पर PUT विधि का उपयोग करना चाहिए।

दूसरे आप Json का सेवन कर रहे हैं तो आप JsonNode या Object को RequestBody के रूप में उपयोग कर सकते हैं। (स्ट्रिंग सही विकल्प नहीं होगा क्योंकि यह कुछ भी स्वीकार कर सकता है (मेरा मतलब है भ्रष्ट जेसन बॉडी इत्यादि)

अगर मैं तुम होते तो मैं JsonNode चुनता।

@RequestMapping(
        path = "/my/endpoint", method= RequestMethod.PUT
        consumes = "application/vnd.mycompany.myservice-v1.hal+json"
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final JsonNode/Object myString
) 

या,

@PutMapping(
        path = "/my/endpoint",
        consumes = "application/vnd.mycompany.myservice-v1.hal+json"
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final JsonNode/Object myString
) 
0
priyranjan 25 नवम्बर 2020, 00:44

आप अनुरोध वस्तु बना सकते हैं

public class MyObject{
private String myStr;

}

MyObject वर्ग का उपयोग RequestBody ऑब्जेक्ट के रूप में mediaType="application/json" के साथ करें

आपके नियंत्रक में

@RequestMapping(
        value= "/my/endpoint", method= RequestMethod.PUT
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final MyObject myObj
) 
0
Banyenzachi 25 नवम्बर 2020, 01:38