在Spring MVC控制器中反序列化单属性JSON有效负载
我想创建在语义上如下所示的控制器方法
public HttpEntity<?> deleteUser(String userId){...
}
客户端将传递用户ID作为JSON有效负载的一部分。如果我尝试注释@RequestBody
字符串参数并发出{"userId":"foo"}
有效负载,则会出现异常
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token at [Source: java.io.PushbackInputStream@7311a203; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) ~[jackson-databind-2.6.1.jar:2.6.1]
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:854) ~[jackson-databind-2.6.1.jar:2.6.1]
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:62) ~[jackson-databind-2.6.1.jar:2.6.1]
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11) ~[jackson-databind-2.6.1.jar:2.6.1]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3702) ~[jackson-databind-2.6.1.jar:2.6.1]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2798) ~[jackson-databind-2.6.1.jar:2.6.1]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:221) ~[spring-web-4.2.0.RELEASE.jar:4.2.0.RELEASE]
这是合理的,因为JSON希望将复杂的对象(即具有一个属性)反序列化为String
。
我也知道这"foo"
是无效的JSON。而且我知道我 使用a Map<String,Object>
甚至更好的a
ModelMap
,并且作为最后的选择,我可以使用查询字符串and @RequestParam
,
今天老板明确要求我找到一种使用纯字符串而不是对象的方法,为了使代码看起来更具可读性。
如何强制Jackson / MVC仅将“ username”属性反序列化为普通格式String
?
回答:
当Spring MVC找到与URL路径匹配的请求映射,但参数(或标头或其他内容)与处理程序方法期望的不匹配时,通常会看到这种类型的错误。
如果使用@RequestBody批注,则Spring MVC希望将POST请求的整个主体映射到Object,默认情况下,它不使用String。
回答:
将deleteUser()方法类型的方法类型更改为GET而不是Post,并使用userId作为String。
您只需将HttpServletRequest注入您的方法并读取正文:
public void deleteUser(HttpServletRequest request) { String userID = IOUtils.toString( request.getInputStream());
// do stuff
}
使用可以替换String参数的包装器(JSON对象的Java模型),这也可以与帖子中的json一起正常工作。
public class UserWrapper { private String userId;
//getter setters
然后在您的控制器中用作:
public void deleteUser(@RequestBody UserWrapper user) {//do your stuff
}
Spring提供了一种配置多个消息转换器的方法,如下所示: 然后,对各种方法的请求必须使用适当的值指定“ content-
type”标头。对于那些将请求主体映射到JAXB bean的方法,请指定“ application /
xml”。对于那些请求主体是字符串的用户,请使用“文本/纯文本”。
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters">
<list>
<ref bean="jsonConverter" />
<ref bean="marshallingConverter" />
<ref bean="stringHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean id="marshallingConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxb2Marshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/plain"/>
</bean>
希望这对您有所帮助!
以上是 在Spring MVC控制器中反序列化单属性JSON有效负载 的全部内容, 来源链接: utcz.com/qa/399419.html