Как получить String Pattern Match из тела http get - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь отфильтровать это тело ответа, которое я получаю, используя Enum.filter и String.match 'тело ответа. Как мне поступить?

iex(15)>  response = HTTPoison.get!("http://127.0.0.1:8081/service/rest/v1/repositories")       
%HTTPoison.Response{
  body: "[ {\n  \"name\" : \"maven-snapshots\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-central\",\n  \"format\" : \"maven2\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n    }\n  }\n}, {\n  \"name\" : \"nuget-group\",\n  \"format\" : \"nuget\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget.org-proxy\",\n  \"format\" : \"nuget\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n    }\n  }\n}, {\n  \"name\" : \"maven-releases\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget-hosted\",\n  \"format\" : \"nuget\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-public\",\n  \"format\" : \"maven2\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"Taskmaster1\",\n  \"format\" : \"docker\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n  \"attributes\" : { }\n} ]",
  headers: [
    {"Date", "Sun, 27 Oct 2019 20:39:44 GMT"},
    {"Server", "Nexus/3.19.1-01 (OSS)"},
    {"X-Content-Type-Options", "nosniff"},
    {"Content-Type", "application/json"},
    {"Content-Length", "1411"} 
  ],
  request: %HTTPoison.Request{
    body: "",
    headers: [],
    method: :get,
    options: [],
    params: %{},
    url: "http://127.0.0.1:8081/service/rest/v1/repositories"
  },
  request_url: "http://127.0.0.1:8081/service/rest/v1/repositories",
  status_code: 200
}

Это ошибка, которую я получаю:

iex(16)> Enum.filter(response.body, fn {key, _} -> String.match?(key, ~r/\A\n  \"format\" : \"docker\"\z/i) end)
** (Protocol.UndefinedError) protocol Enumerable not implemented for "[ {\n  \"name\" : \"maven-snapshots\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-central\",\n  \"format\" : \"maven2\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n    }\n  }\n}, {\n  \"name\" : \"nuget-group\",\n  \"format\" : \"nuget\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget.org-proxy\",\n  \"format\" : \"nuget\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n    }\n  }\n}, {\n  \"name\" : \"maven-releases\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget-hosted\",\n  \"format\" : \"nuget\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-public\",\n  \"format\" : \"maven2\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"Taskmaster1\",\n  \"format\" : \"docker\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n  \"attributes\" : { }\n} ]" of type BitString. This protocol is implemented for the following type(s): Ecto.Adapters.SQL.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashSet, Range, Map, Function, List, Stream, Date.Range, HashDict, GenEvent.Stream, MapSet, File.Stream, IO.Stream
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) lib/enum.ex:141: Enumerable.reduce/3
    (elixir) lib/enum.ex:3023: Enum.filter/2

Работает с заголовками, но не с телом:

iex(16)>  response = HTTPoison.get!("http://127.0.0.1:8081/service/rest/v1/repositories")                       
%HTTPoison.Response{
  body: "[ {\n  \"name\" : \"maven-snapshots\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-snapshots\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-central\",\n  \"format\" : \"maven2\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-central\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://repo1.maven.org/maven2/\"\n    }\n  }\n}, {\n  \"name\" : \"nuget-group\",\n  \"format\" : \"nuget\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-group\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget.org-proxy\",\n  \"format\" : \"nuget\",\n  \"type\" : \"proxy\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget.org-proxy\",\n  \"attributes\" : {\n    \"proxy\" : {\n      \"remoteUrl\" : \"https://www.nuget.org/api/v2/\"\n    }\n  }\n}, {\n  \"name\" : \"maven-releases\",\n  \"format\" : \"maven2\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-releases\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"nuget-hosted\",\n  \"format\" : \"nuget\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/nuget-hosted\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"maven-public\",\n  \"format\" : \"maven2\",\n  \"type\" : \"group\",\n  \"url\" : \"http://127.0.0.1:8081/repository/maven-public\",\n  \"attributes\" : { }\n}, {\n  \"name\" : \"Taskmaster1\",\n  \"format\" : \"docker\",\n  \"type\" : \"hosted\",\n  \"url\" : \"http://127.0.0.1:8081/repository/Taskmaster1\",\n  \"attributes\" : { }\n} ]",
  headers: [
    {"Date", "Sun, 27 Oct 2019 20:47:30 GMT"},
    {"Server", "Nexus/3.19.1-01 (OSS)"},
    {"X-Content-Type-Options", "nosniff"},
    {"Content-Type", "application/json"},
    {"Content-Length", "1411"} 
  ],
  request: %HTTPoison.Request{
    body: "",
    headers: [],
    method: :get,
    options: [],
    params: %{},
    url: "http://127.0.0.1:8081/service/rest/v1/repositories"
  },
  request_url: "http://127.0.0.1:8081/service/rest/v1/repositories",
  status_code: 200
}
iex(17)> Enum.filter(response.headers, fn {key, _} -> String.match?(key, ~r/\Adate\z/i) end)                    
[{"Date", "Sun, 27 Oct 2019 20:47:30 GMT"}]

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Во-первых, лучший способ фильтрации заголовка выглядит следующим образом:

Enum.filter(response.headers, &match?({"Date", _}, &1))

Вывод:

[{"Date", "Sun, 27 Oct 2019 20:47:30 GMT"}]

Для тела вы должны сначала декодировать его из JSON. Вам нужно выбрать библиотеку JSON и добавить ее в mix.exs. Я использую Джейсон . Тогда вы можете сопоставить так же, как указано выше:

Jason.decode!(request.body) |> Enum.filter(&match?(%{"name" => "maven-central"}, &1))

Вывод:

[
  %{
    "attributes" => %{
      "proxy" => %{"remoteUrl" => "https://repo1.maven.org/maven2/"}
    },
    "format" => "maven2",
    "name" => "maven-central",
    "type" => "proxy",
    "url" => "http://127.0.0.1:8081/repository/maven-central"
  }
]
0 голосов
/ 28 октября 2019

Тело является строкой, поэтому функции Enum не работают с ним. Кажется, это что-то вроде JSON, поэтому вы, возможно, захотите сначала проанализировать его в структуре данных. Вы можете сделать это, используя несколько библиотек эликсира, например, Poison :

response.body
|> Poison.decode!()
|> Enum.filter(fn item ->
  item["format"] == "docker"
end)
|> IO.inspect()

производит:

[
  %{
    "attributes" => %{},
    "format" => "docker",
    "name" => "Taskmaster1",
    "type" => "hosted",
    "url" => "http://127.0.0.1:8081/repository/Taskmaster1"
  }
]
...