在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

回到顶部