【问题标题】:Spring REST: HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8'Spring REST:HttpMediaTypeNotSupportedException:内容类型'application/json;charset=UTF-8'
【发布时间】:2013-05-09 00:42:16
【问题描述】:

我收到上述错误,因为 Jackson 尝试反序列化我的 POJO 时出现问题。

我已经调试了代码,它在 Jackson 的 ObjectMapper 中返回 false:

public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
    JavaType javaType = getJavaType(type, contextClass);
    return (this.objectMapper.canDeserialize(javaType) && canRead(mediaType));
}

this.objectMapper.canDeserialize(javaType) 返回 false 导致错误

我的控制器如下:

@Controller
public class CancelController {
    @Autowired
    private CancelService cancelService;

    @RequestMapping( value="/thing/cancel", method=RequestMethod.POST, consumes="application/json" )
    public @ResponseBody CancelThingResponseDTO cancelThing(@RequestBody CancelRequestDTO cancelThingRequest) {
        return cancelService.cancelThing(cancelThingRequest);
    }

我的 CancelRequestDTO 实现了 Serializable:

public class CancelRequestDTO implements Serializable{
  /**
   * Default serialization ID
   */
  private static final long serialVersionUID = 1L;
  /**
   * Reason code associated with the request
   */
  private final String reasonCode;
  /**
   * Identifier of the entity associated with the request
   */
  private final EntityIdentifier entityIdentifier;

  /**
   * Default constructor
   *
   * @param reasonCode Reason code associated with the request
   * @param entityIdentifier Identifier of the entity associated with the request
   */
  public CancelRequestDTO(String reasonCode, EntityIdentifier entityIdentifier) {
    super();
    this.reasonCode = reasonCode;
    this.entityIdentifier = entityIdentifier;
  }
  /**
   * @return Returns the reasonCode.
   */
  public String getReasonCode() {
    return reasonCode;
  }
  /**
   * @return Returns the entityIdentifier.
   */
  public EntityIdentifier getEntityIdentifier() {
    return entityIdentifier;
  }
}

我的Spring配置如下:

<!-- DispatcherServlet Context: defines this servlet's request-processing
    infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />

<!-- Scan for stereotype annotations -->
<context:component-scan base-package="com.cancel.web.controller" />

<bean id="viewNameTranslator"
    class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />





<bean id="jsonView"
    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" >
    <property name="contentType" value="application/json;charset=UTF-8"/>
    </bean>

<!-- Register JSON Converter for RESTful Web Service -->
<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean
                class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            </bean>
        </list>
    </property>
</bean>

有人知道可能导致此反序列化问题的原因吗?

谢谢

【问题讨论】:

  • 出错的 DTO/POJO 的完整代码是什么?
  • 刚刚加了,会不会和没有setter有关?

标签: json spring-mvc jackson


【解决方案1】:

我一直使用 ContentNegotiatingViewResolver 来完成此操作。似乎它不理解您传递的内容类型。这是我通常用来做你想做的事情的配置:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1" />
    <property name="contentNegotiationManager">
        <bean class="org.springframework.web.accept.ContentNegotiationManager">
            <constructor-arg>
                <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
                    <constructor-arg>
                        <map>
                            <entry key="json" value="application/json" />
                            <entry key="xml" value="application/xml" />
                        </map>
                    </constructor-arg>
                </bean>
            </constructor-arg>
        </bean>
    </property>

    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                        <property name="autodetectAnnotations" value="true" />
                    </bean>
                </constructor-arg>
            </bean>
        </list>
    </property>
</bean>

该视频完全按照您在 UI 中通过 jQuery 使用服务所做的工作:

http://pluralsight.com/training/Courses/TableOfContents/springmvc-intro

【讨论】:

  • 还是一样,虽然是charset相关的错误,但和ObjectMapper中的序列化有关
【解决方案2】:

由于我的 DTO 没有带有 setter 的默认构造函数!所以看起来像是杰克逊的一个不准确的例外

【讨论】:

  • 是的,他们的例外可能会误导我。
  • 在我的例子中,我的 DTO 有一个 Map 作为其属性。当我将 @JsonIgnore 添加到此属性时,它解决了我的问题。
  • 在我的例子中,a为属性compiled创建了一个方法getCompiledisCompiled,错误来自Jackson。
【解决方案3】:

对于仍然面临此问题的任何人,您不能在一个类中拥有两个 @JsonBackReference,向其中一个引用添加值 @JsonBackReference(value = "secondParent") 也向父类中的 @JsonManagedReference(value ="secondParent") 添加相同的值。

【讨论】:

    猜你喜欢
    • 2020-03-20
    • 1970-01-01
    • 2018-08-06
    • 2018-07-24
    • 2019-12-16
    • 2015-11-01
    • 1970-01-01
    • 2016-12-07
    • 2019-10-09
    相关资源
    最近更新 更多