JsonParseException:无效的 UTF-8 中间字节 0x20 与 MockMVC 和 Maven
JsonParseException: Invalid UTF-8 middle byte 0x20 with MockMVC and Maven
编辑:如果我删除 spring-restdoc 代码,测试通过 maven。
我正在尝试在 Spring 启动网络应用程序中使用 MockMVC 编写集成测试。
我现在只有一个测试(下面的步骤和代码),如果我在 运行 它在 IDE 中通过,但如果由 Maven 执行,则失败并显示以下堆栈跟踪:
org.springframework.restdocs.payload.PayloadHandlingException: com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 middle byte 0x20
at [Source: [B@3793896e; line: 30, column: 23]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1419)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:508)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:3223)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:3230)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._decodeUtf8_3fast(UTF8StreamJsonParser.java:3036)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2216)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:2165)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:279)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:441)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:574)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:423)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapArray(UntypedObjectDeserializer.java:510)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:437)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:552)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:423)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2230)
at org.springframework.restdocs.payload.JsonContentHandler.readContent(JsonContentHandler.java:81)
at org.springframework.restdocs.payload.JsonContentHandler.findMissingFields(JsonContentHandler.java:49)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:112)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:73)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:64)
at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:101)
at org.springframework.test.web.servlet.MockMvc.andDo(MockMvc.java:158)
代码:
我添加了 starter-test 依赖项,并为所有未来的测试创建了一个超级 class:
@Ignore
@MappedSuperclass
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@ActiveProfiles(value = {"test"})
public class IntegrationTest
{
@Autowired
WebApplicationContext context;
MockMvc mockMvc;
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Before
public void setUp()
{
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).build();
}
}
然后我创建了这个测试:
public class PostsTest extends IntegrationTest
{
@Test
public void getAll() throws Exception
{
mockMvc.perform(get("/api/v1/posts").accept(MediaType.APPLICATION_JSON_VALUE)
.andExpect(status().isOk())
.andDo(document("posts-index", preprocessResponse(prettyPrint()), responseFields(
fieldWithPath("data").description("The response payload"),
fieldWithPath("data.[].id").description("ID"),
fieldWithPath("data.[].title").description("Title"),
fieldWithPath("data.[].body").description("Content"),
fieldWithPath("data.[].type").description("Type"),
fieldWithPath("data.[].createdAt").description("Creation date"),
fieldWithPath("data.[].modifiedAt").description("Last edit date"),
fieldWithPath("data.[].entityType").description("Entity type"),
fieldWithPath("meta").description("The response metadata")
)));
}
}
您在某个时候正在解析 json,我怀疑它是从文件中读取的。
该文件似乎以错误的编码保存,例如 ISO-8859-1。确保它以 UTF-8、UTF-16 或 UTF-32 格式保存。大多数 JSON 解析器都是从前四个字节猜测编码,如果发现不支持的编码就会失败。
我发现从 restdocs 代码中删除 preprocessResponse(prettyPrint())
,测试通过。
编辑:正如 Andy Wilkinson 在评论中所报告的,此错误已在 spring-restdocs
的 1.0.2.BUILD-SNAPSHOT
版本中修复。
编辑:如果我删除 spring-restdoc 代码,测试通过 maven。
我正在尝试在 Spring 启动网络应用程序中使用 MockMVC 编写集成测试。
我现在只有一个测试(下面的步骤和代码),如果我在 运行 它在 IDE 中通过,但如果由 Maven 执行,则失败并显示以下堆栈跟踪:
org.springframework.restdocs.payload.PayloadHandlingException: com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 middle byte 0x20
at [Source: [B@3793896e; line: 30, column: 23]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1419)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:508)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:3223)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:3230)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._decodeUtf8_3fast(UTF8StreamJsonParser.java:3036)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2216)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:2165)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:279)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:441)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:574)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:423)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapArray(UntypedObjectDeserializer.java:510)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:437)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:552)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:423)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2230)
at org.springframework.restdocs.payload.JsonContentHandler.readContent(JsonContentHandler.java:81)
at org.springframework.restdocs.payload.JsonContentHandler.findMissingFields(JsonContentHandler.java:49)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:112)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:73)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:64)
at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:101)
at org.springframework.test.web.servlet.MockMvc.andDo(MockMvc.java:158)
代码:
我添加了 starter-test 依赖项,并为所有未来的测试创建了一个超级 class:
@Ignore
@MappedSuperclass
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@ActiveProfiles(value = {"test"})
public class IntegrationTest
{
@Autowired
WebApplicationContext context;
MockMvc mockMvc;
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Before
public void setUp()
{
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).build();
}
}
然后我创建了这个测试:
public class PostsTest extends IntegrationTest
{
@Test
public void getAll() throws Exception
{
mockMvc.perform(get("/api/v1/posts").accept(MediaType.APPLICATION_JSON_VALUE)
.andExpect(status().isOk())
.andDo(document("posts-index", preprocessResponse(prettyPrint()), responseFields(
fieldWithPath("data").description("The response payload"),
fieldWithPath("data.[].id").description("ID"),
fieldWithPath("data.[].title").description("Title"),
fieldWithPath("data.[].body").description("Content"),
fieldWithPath("data.[].type").description("Type"),
fieldWithPath("data.[].createdAt").description("Creation date"),
fieldWithPath("data.[].modifiedAt").description("Last edit date"),
fieldWithPath("data.[].entityType").description("Entity type"),
fieldWithPath("meta").description("The response metadata")
)));
}
}
您在某个时候正在解析 json,我怀疑它是从文件中读取的。
该文件似乎以错误的编码保存,例如 ISO-8859-1。确保它以 UTF-8、UTF-16 或 UTF-32 格式保存。大多数 JSON 解析器都是从前四个字节猜测编码,如果发现不支持的编码就会失败。
我发现从 restdocs 代码中删除 preprocessResponse(prettyPrint())
,测试通过。
编辑:正如 Andy Wilkinson 在评论中所报告的,此错误已在 spring-restdocs
的 1.0.2.BUILD-SNAPSHOT
版本中修复。