【问题标题】:How to pass a JSON array as a parameter in URL如何将 JSON 数组作为 URL 中的参数传递
【发布时间】:2015-02-19 02:10: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

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

【问题讨论】:

  • 为什么不把body里面的数据传进去?
  • @bjoernhaeuser 你能指导我如何通过身体吗?
  • 你用什么来做请求?这不在上面的代码中。
  • @bjoernhaeuser 对不起,我没听懂你。你能告诉我你想知道什么

标签: java json spring web-services


【解决方案1】:

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

它甚至可以处理循环依赖(感谢json-stringify-safe)。

尽管如此,我还在其之上构建了一个序列化程序来删除不必要的数据(因为不建议使用超过 2k 字符的 url,请参阅What is the maximum length of a URL in different browsers?

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);
    });
  });
});

【讨论】:

    【解决方案2】:
    let qs = event.queryStringParameters;
    const query = Object.keys(qs).map(key => key + '=' + qs[key]).join('&');
    

    【讨论】:

      【解决方案3】:

      我知道这是旧的,但如果其他人想知道为什么他们得到不完整的 json 像上面是因为 & 符号 &amp; 是 URL 中用于分隔参数的特殊字符。
      在您的数据中,R&amp;R 中有一个 & 符号。所以 acc 参数在到达 & 字符时结束。

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

      【讨论】:

        【解决方案4】:

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

        如此有效地发送了第二个名为 R" 的参数。您应该 urlencode 您的字符串。POST 不是一个选项吗?

        【讨论】:

        • 如何在 Web 服务中 POST 以及如何对字符串进行 URLEncode?​​span>
        【解决方案5】:

        我建议将正文中的 JSON 数据作为POST 请求传递。但如果您仍想将其作为 URL 中的参数传递,则必须像下面这样对您的 URL 进行编码,例如:-

        对于 ex json 是 :->{"name":"ABC","id":"1"}

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

        有关 URL 编码的更多信息,请参阅下文

        https://en.wikipedia.org/wiki/Percent-encoding

        【讨论】:

        • 你能告诉我如何使用 POST 传递
        • 你在前端使用什么,我的意思是向spring服务提出请求?是 AJAX 还是 JAVA 还是什么??
        • 这是一个网络服务调用。Android 人员必须向我发送数据,我必须保存在数据库中。
        • 他们使用哪种语言进行此 Web 服务调用?
        • 对于 POST 方法支持,您必须更改您的 Spring 服务,例如 @RequestMapping(value ="/saveName",method = RequestMethod.POST) @ResponseBody public String saveName(@RequestBody String acc) { jsonObject = 新 JSONObject();尝试 { ); System.out.println(acc); jsonObject.accumulate("结果", "保存"); } catch(Exception e) { e.printStackTrace();jsonObject.accumulate("result", "Error Occured"); } 返回 jsonObject.toString(); } 并让你的 Android guyz 发出 POST 请求,就这样。
        【解决方案6】:

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

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

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

        【讨论】:

        • 这应该是解决方案。在某些情况下,API 仅限于 GET,这个想法拯救了我!
        • 你不需要 base64。 encodeURIComponent() 应该没问题。
        • @lenooh 是的,它会起作用,但你需要它,因为 encodeURIComponent() 会在 URL 中添加字符(每个非字母字符可能 2 或 3 个),并且你可能会填写 2048 个字符的 URL限制非常快。 Base64 将尝试以二进制形式编码,因此,它会得到更少的字符。
        • Base64 对于 URL 不安全,如答案中给出的链接中所述。替代方案是 a) Use different 64 characters: base64url 或 b) urlencode the base64 data
        【解决方案7】:

        将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);
        
        ?>
        

        【讨论】:

          【解决方案8】:

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

          例如,如果您使用 php,则可以这样做(在其他语言中使用适当的 json 解码):

          服务器请求:

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

          在服务器中:

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

          输出:

          89
          

          【讨论】:

            【解决方案9】:

            您可以通过这种方式将您的 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 方法

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-03-22
              • 2010-12-18
              • 2020-04-29
              • 2017-03-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多