我正在使用Spring Framework
版本4.3.6
。
它适用于RestTemplate
,因此支持XML
和JSON
提醒:关于HTTP
方法,POST
和PUT
有义务强制定义Content-Type
标头。它适用于XML
或JSON
。
我对RequestEntity<Object>
有关于测试的情况:
我为POST
RequestEntity<Object> requestEntity =
RequestEntity.post(uri).contentType(MediaType.APPLICATION_XML)
.header("Accept-Language", locale.toString())
.body(entity);
直到这里,当服务器没有抛出任何异常时它才能正常工作。这意味着,实体可以毫无问题地保存或保存在数据库中。
在其他测试场景中,实体已存在于数据库中时出现问题。我有@ControllerAdvice
通过@ExceptionHandler
工作。服务器端的工作方式如何。它捕获异常并生成错误消息但是......
...问题仅与XML
一起发生,我收到以下错误消息(当然@Test
方法失败)
org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'
at [row,col {unknown-source}]: [1,1]; nested exception is java.io.IOException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'
at [row,col {unknown-source}]: [1,1]
我确实意识到通过以下版本避免错误消息的独特方法:
RequestEntity<Object> requestEntity =
RequestEntity.post(uri).contentType(MediaType.APPLICATION_XML)
.accept(MediaType.APPLICATION_XML)//<---- new
.header("Accept-Language", locale.toString())
.body(entity);
我很困惑,为什么它有效,因为POST
不是必须定义Accept
标头。即使在服务器端,我也可以为ResponseEntity<Object>
(响应)定义Content-Type
和Accept
标头到XML
的值,{{ 1}}失败了。解决此问题的唯一方法是为@Test
(请求)添加RequestEntity<Object>
部分。
这里的另一个问题是我们必须假设使用.accept(MediaType.APPLICATION_XML)
的其他Java开发人员将创建RestTemplate
对象,只需定义RequestEntity<Object>
和而不用定义Content-Type
标题。
注意:即使Accept
使用RestTemplate
方法
同样,它只发生在setErrorHandler
,对于XML
我有以下内容:
JSON
并且始终适用于有效和无效(已保留的实体)方案。
解决这种情况的最佳方法是什么?
α
即使我做了以下版本的建议:
RequestEntity<Object> requestEntity =
RequestEntity.post(uri).contentType(MediaType.APPLICATION_JSON_UTF8)
.header("Accept-Language", locale.toString())
.body(entity);
我得到同样的情况
关于@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true)
.favorParameter(false)
.ignoreAcceptHeader(false)
//.defaultContentType(new MediaType(MediaType.TEXT_PLAIN, StandardCharsets.UTF_8))
.defaultContentType(new MediaType(MediaType.APPLICATION_XML, StandardCharsets.UTF_8))
.mediaType("html", MediaType.TEXT_HTML)
.mediaType("xml", new MediaType(MediaType.APPLICATION_XML, StandardCharsets.UTF_8))
.mediaType("json", MediaType.APPLICATION_JSON_UTF8);
}
,我不使用XML
,因为它不支持通用收藏,因此我使用了杰克逊jackson-dataformat-xml
重要我只有在JAXB2
与RequestEntity<Object>
一起使用时才会出现这种情况,以便进行其他测试
RestTemplate
观察,没有 ResultActions resultActions =
mockMvc.perform(post(uri).contentType(MediaType.APPLICATION_XML)
.header("Accept-Language", locale.toString())
.content(entity)).andDo(print());
句。
一切正常。
答案 0 :(得分:1)
Application/json
可能已在某处的服务应用程序中配置为默认媒体类型。这就是为什么除非你将Accept
标题指定为application/xml
,否则你会得到json响应。
如果要使application/xml
成为默认的响应媒体类型,则需要配置ContentNegotiationManagerFactoryBean
(可能您已经在执行此操作但是对于application / json)。像这样:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Setup a simple strategy: use all the defaults and return XML by default when not sure.
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_XML);
}
}
您可以在spring文档here中找到它。
您需要关注的另一件事是您在错误场景中使用的实体。如果使用Jaxb注释(@XmlRootElement
)