java - वसंत एमवीसी: JSON अनुरोध निकाय deserialize नहीं है




spring-mvc (4)

आप @RequestBody पूरी तरह से बचने की कोशिश कर सकते हैं और इसके बजाय अनुरोध निकाय सीधे InputStream / Reader या WebRequest / HttpServletRequest

मैं एक स्प्रिंग एमवीसी प्रोजेक्ट पर काम कर रहा हूं और मुझे जो कार्यों की आवश्यकता है, उनमें से एक मुझे POST अनुरोध में उपयोगकर्ता द्वारा भेजे गए JSON डेटा की एक स्ट्रिंग की आवश्यकता है। मुझे पता है कि वसंत जैक्सन का उपयोग वस्तुओं के लिए JSON का उपयोग करेगा, लेकिन अगर मैं निम्न की तरह कुछ कोशिश करता हूं:

@RequestMapping(value = "/test", method = RequestMethod.POST)
public void doSomething(@RequestBody String json) {
    // do something
}

मुझे बस HTTP 400 खराब अनुरोध वापस मिलता है ("क्लाइंट द्वारा भेजा गया अनुरोध वाक्यगत रूप से गलत था।")।

क्लाइंट द्वारा स्ट्रिंग के रूप में भेजे गए कच्चे JSON को मैं कैसे प्राप्त कर सकता हूं?


आपको आमतौर पर इस प्रकार की त्रुटि दिखाई देगी जब स्प्रिंग एमवीसी को एक अनुरोध मैपिंग मिलती है जो यूआरएल पथ से मेल खाता है लेकिन पैरामीटर (या हेडर या कुछ) हैंडलर विधि की अपेक्षा करने वाले मेल नहीं खाते हैं।

यदि आप @RequestBody एनोटेशन का उपयोग करते हैं तो मेरा मानना ​​है कि स्प्रिंग एमवीसी एक अनुरोध के लिए POST अनुरोध के पूरे शरीर को मानचित्र करने की उम्मीद कर रहा है। मुझे लगता है कि आपका शरीर बस एक स्ट्रिंग नहीं है, लेकिन कुछ पूर्ण JSON ऑब्जेक्ट है।

यदि आपके पास JSON ऑब्जेक्ट का जावा मॉडल है, तो आप उम्मीद कर रहे हैं कि आप स्ट्रिंग पैरामीटर को इसके साथ बदल सकते हैं। कुछ घोषणा, जैसे कि

public void doSomething(@RequestBody MyObject myobj) {

यदि आपके पास जावा ऑब्जेक्ट नहीं है जो JSON से मेल खाता है तो आप String प्रकार को Map<String, Object> साथ बदलकर काम कर सकते हैं और देख सकते हैं कि यह आपको एक समाधान समाधान के करीब ले जाता है या नहीं।

स्प्रिंग एमवीसी में डीबग लॉगिंग भी चालू कर सकते हैं ताकि यह एक बुरा अनुरोध क्यों हो।

संपादित करें: टिप्पणियों में अपनी आवश्यकताओं को देखते हुए, आप बस अपनी विधि में HttpServletRequest इंजेक्ट कर सकते हैं और शरीर को स्वयं पढ़ सकते हैं।

public void doSomething(HttpServletRequest request) {
  String jsonBody = IOUtils.toString( request.getInputStream());
  // do stuff
}

यदि आपका कंटेंट-टाइप "एप्लिकेशन / जेसन" है और आपका पहला संदेश कनवर्टर org.springframework.http.converter.StringHttpMessageConverter नहीं है, वसंत सही काम नहीं कर सका। मेरे मामले में, मैंने यह किया:

<mvc:annotation-driven>
		<mvc:message-converters>
			<ref bean="stringHttpMessageConverter" /><!-- 放在前面,对@RequestBody String json 提供支持 -->
			<ref bean="mappingJacksonHttpMessageConverter" />
		</mvc:message-converters>
	</mvc:annotation-driven>


	<!-- 消息转换器 -->
	<bean id="stringHttpMessageConverter"
		class="org.springframework.http.converter.StringHttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<bean class="org.springframework.http.MediaType">
					<constructor-arg index="0" value="text" />
					<constructor-arg index="1" value="plain" />
					<constructor-arg index="2" value="UTF-8" />
				</bean>
				<bean class="org.springframework.http.MediaType">
					<constructor-arg index="0" value="application" />
					<constructor-arg index="1" value="json" />
					<constructor-arg index="2" value="UTF-8" />
				</bean>
			</list>
		</property>
	</bean>

	<bean id="mappingJacksonHttpMessageConverter"
		class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<bean class="org.springframework.http.MediaType">
					<constructor-arg index="0" value="text" />
					<constructor-arg index="1" value="plain" />
					<constructor-arg index="2" value="UTF-8" />
				</bean>
				<bean class="org.springframework.http.MediaType">
					<constructor-arg index="0" value="application" />
					<constructor-arg index="1" value="json" />
					<constructor-arg index="2" value="UTF-8" />
				</bean>
			</list>
		</property>
		<!-- 设置时间格式, 有了这个就不用在pojo的属性上写了 -->
		<property name="objectMapper">
			<bean class="com.fasterxml.jackson.databind.ObjectMapper">
				<property name="dateFormat">
					<bean class="java.text.SimpleDateFormat">
						<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"></constructor-arg>
					</bean>
				</property>
			</bean>
		</property>
	</bean>


वसंत संस्करण अद्यतन के साथ मेरे लिए यह सिर्फ "जरूरी है।" XXX "XXX के बजाय" और सब ठीक काम कर रहा है जैसा आपके पास है। सामग्री-प्रकार एप्लिकेशन / जेसन





spring-mvc