java - 无法在 URL 中记录 JSON

标签 java json spring spring-restdocs

在我的 Rest API 中,应该可以检索边界框内的数据。因为边界框有四个坐标,所以我想以这种方式设计 GET 请求,让它们接受 JSON 形式的边界框。因此,我需要能够将 JSON 字符串作为 URL 参数发送和记录。

测试本身有效,但我无法使用 Spring RestDocs (1.0.0.RC1) 记录这些请求。我用更简单的方法重现了这个问题。见下文:

  @Test public void ping_username() throws Exception
  {
    String query = "name={\"user\":\"Müller\"}";
    String encodedQuery = URLEncoder.encode(query, "UTF-8");
    mockMvc.perform(get(URI.create("/ping?" + encodedQuery)))
            .andExpect(status().isOk())
            .andDo(document("ping_username"));
  }

当我删除 .andDo(document("ping_username")) 时,测试通过。

堆栈跟踪:

java.lang.IllegalArgumentException: Illegal character in query at index 32: http://localhost:8080/ping?name={"user":"Müller"}
    at java.net.URI.create(URI.java:852)
    at org.springframework.restdocs.mockmvc.MockMvcOperationRequestFactory.createOperationRequest(MockMvcOperationRequestFactory.java:79)
    at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:93)
    at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:158)
    at application.rest.RestApiTest.ping_username(RestApiTest.java:65)

收到对 URL 进行编码的建议后,我尝试了它,但问题仍然存在。

用于在我的测试中创建 URI 的字符串现在为 /ping?name%3D%7B%22user%22%3A%22M%C3%BCller%22%7D

我检查了堆栈跟踪中出现的类 MockMvcOperationRequestFactory,并在第 79 行执行了以下代码:

URI.create(getRequestUri(mockRequest)
                + (StringUtils.hasText(queryString) ? "?" + queryString : ""))

这里的问题是使用了未编码的字符串(在我的例子中http://localhost:8080/ping?name={"user":"Müller"})并且创建URI 失败。

备注:

安迪·威尔金森的回答就是问题的解决方案。尽管我认为 David Sinfield 是对的,并且 URL 中应避免使用 JSON 以保持简单。对于我的边界框,我将使用逗号分隔的字符串,就像 WMS 1.1 中使用的那样。 :BBOX=x1,y1,x2,y2

最佳答案

您没有提到您正在使用的 Spring REST 文档的版本,但我猜测问题出在 URIUtil 上。我无法确定,因为我看不到 URIUtil 来自哪里。

无论如何,使用 JDK 的 URLEncoder 对我来说适用于 Spring REST Docs 1.0.0.RC1:

String query = "name={\"user\":\"Müller\"}";
String encodedQuery = URLEncoder.encode(query, "UTF-8");
mockMvc.perform(get(URI.create("/baz?" + encodedQuery)))
        .andExpect(status().isOk())
        .andDo(document("ping_username"));

然后您可以在服务器端使用URLDecoder.decode来获取原始JSON:

URLDecoder.decode(request.getQueryString(), "UTF-8")

关于java - 无法在 URL 中记录 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32885541/

相关文章:

java - 如何从我发送到 put(Object) 到 map 中的方法返回 List<String> (有示例)

java - 在 jasper 报告中使用 spring beans

java - 如果 3 个按钮相同,如何使用 selenium 代码选择第二个按钮

spring - 如何使用 Spring resource.groovy 正确注入(inject) Grails 服务

Java 8 List<V> 到 Map<K, V> 与函数

java - 为什么我在解析 JSON 时得到 NULL 值

json - ETL - 自动将数据从一个数据库传输到另一个数据库

c# - 反序列化 JSON.NET 中具有不同名称的对象列表

java - 如何在 Spring 中为 View 路径设置自定义 View 解析器

java - 动态创建和读取java类