如何将 JSON 数组作为 URL 中的参数传递

问题描述 投票:0回答:10

我需要在 Web 服务调用中将一些值从移动设备传递到服务器,因此我计划以 JSON 格式传递所有值,如下所示

{
    "nameservice": [
        {
            "id": 7413,
            "name": "ask"
        },
        {
            "id": 7414,
            "name": "josn"
        },
        {
            "id": 7415,
            "name": "john"
        },
        {
            "id": 7418,
            "name": "R&R"
        }
    ]
}

以下是我的服务电话

@RequestMapping("/saveName")
@ResponseBody
public String saveName(String acc)
{jsonObject = new JSONObject();
    try
    {
    );
    System.out.println(acc);
    jsonObject.accumulate("result", "saved ");
    }
    catch(Exception e)
    {
        e.printStackTrace();jsonObject.accumulate("result", "Error Occured ");
    }
    return jsonObject.toString();
}

我正在尝试通过这种方式调用上述服务

localhost:8080/service/saveName?acc={ "nameservice": [ { "id": 7413, "name": "ask" }, { "id": 7414, "name": "josn" }, { "id": 7415, "name": "john" }, { "id": 7418, "name": "R&R" } ] }

但是输出是这样的

{ "nameservice": [ { "id": 7413, "name": "ask" }, { "id": 7414, "name": "josn" }, { "id": 7415, "name": "john" }, { "id": 7418, "name": "R

任何人都可以告诉我为什么我没有得到所有的值吗?

java json spring web-services
10个回答
58
投票

我建议将正文中的 JSON 数据作为

POST
请求传递。但如果您仍然想将其作为 URL 中的参数传递,则必须像下面这样对 URL 进行编码:

JSON 示例:

{"name":"ABC","id":"1"}

编码 URL 示例:

testurl:80/service?data=%7B%22name%22%3A%22ABC%22%2C%22id%22%3A%221%22%7D

有关 URL 编码的更多信息,请参阅percent-encoding


50
投票

我知道这可能是稍后的帖子,但是,对于新访问者,我将分享我的解决方案,因为 OP 要求一种通过 GET 传递 JSON 对象的方法(而不是其他答案中建议的 POST)。

  1. 获取 JSON 对象并将其转换为字符串(JSON.stringify)
  2. 获取字符串并用 Base64 对其进行编码(您可以在here
  3. 找到一些有用的信息)
  4. 将其附加到 URL 并进行 GET 调用
  5. 反转该过程。解码并解析为对象

我在某些只能进行 GET 调用的情况下使用过它并且它有效。此外,这个解决方案实际上是跨语言的。


6
投票

我知道这已经很旧了,但是如果其他人想知道为什么他们会得到像上面这样不完整的 json ,是因为 & 符号

&
是 URL 中用于分隔参数的特殊字符。
在您的数据中,
R&R
中有一个 & 符号。因此 acc 参数在到达 & 字符时结束。

这就是您得到的数据被截断的原因。解决方案是对数据进行 url 编码或像已接受的解决方案建议的那样以 POST 形式发送。


4
投票

& 是下一个参数的关键字,如下所示 你?param1=1¶m2=2

如此有效地发送了名为 R" 的第二个参数。您应该

urlencode
您的字符串。POST 不是一个选项吗?


3
投票

您可以通过这种方式将 json 输入作为 POST 请求以及授权标头传递

public static JSONObject getHttpConn(String json){
        JSONObject jsonObject=null;
        try {
            HttpPost httpPost=new HttpPost("http://google.com/");
            org.apache.http.client.HttpClient client = HttpClientBuilder.create().build();
            StringEntity stringEntity=new StringEntity("d="+json);

            httpPost.addHeader("content-type", "application/x-www-form-urlencoded");
            String authorization="test:test@123";
            String encodedAuth = "Basic " + Base64.encode(authorization.getBytes());        
            httpPost.addHeader("Authorization", security.get("Authorization"));
            httpPost.setEntity(stringEntity);
            HttpResponse reponse=client.execute(httpPost);
            InputStream inputStream=reponse.getEntity().getContent();
            String jsonResponse=IOUtils.toString(inputStream);
            jsonObject=JSONObject.fromObject(jsonResponse);
            } catch (UnsupportedEncodingException e) {

            e.printStackTrace();
        } catch (ClientProtocolException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }
        return jsonObject;


    }

此方法将返回 json 响应。同样您可以使用 GET 方法


1
投票

我遇到了同样的需求,并制作了一个与 Next.js 框架配合使用的通用解决方案(节点+浏览器)。

它甚至可以处理循环依赖(感谢

json-stringify-safe
)。

尽管如此,我还在其上构建了一个序列化器以删除不必要的数据(因为不建议使用超过 2k 个字符的 url,请参阅不同浏览器中 URL 的最大长度是多少?

import StringifySafe from 'json-stringify-safe';

export const encodeQueryParameter = (data: object): string => {
  return encodeURIComponent(StringifySafe(data)); // Use StringifySafe to avoid crash on circular dependencies
};

export const decodeQueryParameter = (query: string): object => {
  return JSON.parse(decodeURIComponent(query));
};

还有单元测试(开玩笑):

import { decodeQueryParameter, encodeQueryParameter } from './url';

export const data = {
  'organisation': {
    'logo': {
      'id': 'ck2xjm2oj9lr60b32c6l465vx',
      'linkUrl': null,
      'linkTarget': '_blank',
      'classes': null,
      'style': null,
      'defaultTransformations': { 'width': 200, 'height': 200, '__typename': 'AssetTransformations' },
      'mimeType': 'image/png',
      '__typename': 'Asset',
    },
    'theme': {
      'primaryColor': '#1134e6',
      'primaryAltColor': '#203a51',
      'secondaryColor': 'white',
      'font': 'neuzeit-grotesk',
      '__typename': 'Theme',
      'primaryColorG1': '#ffffff',
    },
  },
};
export const encodedData = '%7B%22organisation%22%3A%7B%22logo%22%3A%7B%22id%22%3A%22ck2xjm2oj9lr60b32c6l465vx%22%2C%22linkUrl%22%3Anull%2C%22linkTarget%22%3A%22_blank%22%2C%22classes%22%3Anull%2C%22style%22%3Anull%2C%22defaultTransformations%22%3A%7B%22width%22%3A200%2C%22height%22%3A200%2C%22__typename%22%3A%22AssetTransformations%22%7D%2C%22mimeType%22%3A%22image%2Fpng%22%2C%22__typename%22%3A%22Asset%22%7D%2C%22theme%22%3A%7B%22primaryColor%22%3A%22%231134e6%22%2C%22primaryAltColor%22%3A%22%23203a51%22%2C%22secondaryColor%22%3A%22white%22%2C%22font%22%3A%22neuzeit-grotesk%22%2C%22__typename%22%3A%22Theme%22%2C%22primaryColorG1%22%3A%22%23ffffff%22%7D%7D%7D';

describe(`utils/url.ts`, () => {
  describe(`encodeQueryParameter`, () => {
    test(`should encode a JS object into a url-compatible string`, async () => {
      expect(encodeQueryParameter(data)).toEqual(encodedData);
    });
  });

  describe(`decodeQueryParameter`, () => {
    test(`should decode a url-compatible string into a JS object`, async () => {
      expect(decodeQueryParameter(encodedData)).toEqual(data);
    });
  });

  describe(`encodeQueryParameter <> decodeQueryParameter <> encodeQueryParameter`, () => {
    test(`should encode and decode multiple times without altering data`, async () => {
      const _decodedData: object = decodeQueryParameter(encodedData);
      expect(_decodedData).toEqual(data);

      const _encodedData: string = encodeQueryParameter(_decodedData);
      expect(_encodedData).toEqual(encodedData);

      const _decodedDataAgain: object = decodeQueryParameter(_encodedData);
      expect(_decodedDataAgain).toEqual(data);
    });
  });
});

0
投票

@RE350 建议在帖子正文中传递 JSON 数据是理想的选择。但是,您仍然可以将 json 对象作为 GET 请求中的参数发送,在服务器端逻辑中解码 json 字符串并将其用作对象。

例如,如果您使用 php,则可以执行此操作(在其他语言中使用适当的 json 解码):

服务器请求:

http://<php script>?param1={"nameservice":[{"id":89},{"id":3}]}

在服务器中:

$obj = json_decode($_GET['param1'], true);
$obj["nameservice"][0]["id"]

输出:

89

0
投票

发送 Json 数据字符串到网址并使用 post 方法获取结果

在 C# 中

public string SendJsonToUrl(string Url, string StrJsonData)
{
    if (Url == "" || StrJsonData == "") return "";
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
        request.Method = "POST";
        request.ContentType = "application/json";
        request.ContentLength = StrJsonData.Length;
        using (var streamWriter = new StreamWriter(request.GetRequestStream()))
        {
            streamWriter.Write(StrJsonData);
            streamWriter.Close();
            var httpResponse = (HttpWebResponse)request.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                return result;
            }
        }
    }
    catch (Exception exp)
    {
        throw new Exception("SendJsonToUrl", exp);
    }
}

在 PHP 中

<?php

$input = file_get_contents('php://input');
$json = json_decode($input ,true);

?>

0
投票

您可以在 URL 中发送数组,如下所示:

发送每个文件字段[POST_MESSAGE]

https://crm654.com/task.comment.add.json?taskId=625&FIELDS[POST_MESSAGE]='宾果!'


-1
投票
let qs = event.queryStringParameters;
const query = Object.keys(qs).map(key => key + '=' + qs[key]).join('&');
© www.soinside.com 2019 - 2024. All rights reserved.