【问题标题】:Java puts the xml attributes in "request version" part of HTTP requestJava 将 xml 属性放在 HTTP 请求的“请求版本”部分
【发布时间】:2013-11-30 11:40:10
【问题描述】:

我可以使用浏览器发送以下请求并收到正确的响应,但是当我使用以下代码发送它时,服务器返回错误。

我怀疑问题在于 Java 将 xml 属性放在 HTTP 请求的“请求版本”部分。

String QueryString = "http://xml.example.com/service?"
            + "<List>"
            + "<Credentials username=\"example\" password=\"example1\" remoteIp=\"X.X.X.X\"/>"
            + "<Id>10202</Id>"
            + "</List>";

    try {
        URL page = new URL(QueryString);

        StringBuffer text = new StringBuffer();

        HttpURLConnection conn = (HttpURLConnection) page.openConnection();
        conn.connect();

        InputStreamReader in = new InputStreamReader(
                (InputStream) conn.getContent());

我查看了使用 WireShark 发送的请求。

GET /service?<List><Credentials username="example" password="example1" remoteIp="X.X.X.X"/<Id>10202</Id></List>
....
Request URI: /service?<List><Credentials
Request Version: username="example" password="example1" remoteIp="X.X.X.X"/<Id>10202</Id></List> HTTP/1.1

服务器的结果是

  XML document structures must start and end within the same entity.

【问题讨论】:

  • 这非常丑陋(让我强调 VERY),以这样的查询字符串发送数据。请改用 POST 请求的正文。
  • 还有你的问题 - 问题可能是 URI 编码。浏览器正在自动进行编码(没有用户注意到它)。在 Java 代码中,需要手动或语义构造 URL 对象。
  • 看起来您甚至正在尝试像这样进行身份验证。 URL 被转储到访问日志中,因此您将在这些文件中公开用户凭据。
  • @PavelHoral 请你帮我把它放进身体里
  • 通过 JRE 组件发送 POST 可能有点烦人 (mkyong.com/java/how-to-send-http-request-getpost-in-java)。检查 Apache HTTP 组件库...hc.apache.org/httpcomponents-client-ga/tutorial/html/… .

标签: java xml httpurlconnection wireshark


【解决方案1】:

我会回应 cmets 的问题,说在您与之通信的服务器方面,这是一个相当糟糕的表示选择,但如果它是服务提供商提供的唯一选项,那么...... .

如果服务器需要 URI 编码的查询字符串,那么您可以使用 java.net.URI 的多个参数构造函数为您处理必要的转义:

URI uri = new URI("http", "xml.example.com", "/service",
          "<List>"
        + "<Credentials username=\"example\" password=\"example1\" remoteIp=\"X.X.X.X\"/>"
        + "<Id>10202</Id>"
        + "</List>", null);
URL page = uri.toURL();

如果它需要 application/x-www-form-urlencoded 格式(空格是 + 而不是 %20),那么您可以使用 URLEncoder:

URL page = new URL("http://xml.example.com/service?"
    + URLEncoder.encode("<List>"
        + "<Credentials username=\"example\" password=\"example1\" remoteIp=\"X.X.X.X\"/>"
        + "<Id>10202</Id>"
        + "</List>", "UTF-8"));

如果您想在请求正文中发布数据而不是在 URL 中提供数据,那么您需要类似这样的内容(为清楚起见省略了异常处理)。

URL page = new URL("http://xml.example.com/service");
HttpURLConnection connection = page.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/xml"); // or text/xml
connection.setDoOutput(true); // need to call this before you can getOutputStream

// write the XML as UTF-8 (which is what an XML parser will expect as you're
// sending it without an <?xml declaration that says anything different)
Writer writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write("<List>"
        + "<Credentials username=\"example\" password=\"example1\" remoteIp=\"X.X.X.X\"/>"
        + "<Id>10202</Id>"
        + "</List>");
writer.close();

【讨论】:

  • 谢谢,它作为必需的 URI 编码查询字符串工作。实际上服务器需要是 https,我使用 http 的原因是能够使请求和响应可读,并且我也对在帖子正文中包含请求非常感兴趣,你能帮我吗?我应该在一个单独的问题中问这个吗?
  • @Alex 我已经添加了一个如何执行此操作的示例,它与您在one of your earlier questions 中展示的基本相同。
猜你喜欢
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2013-02-08
相关资源
最近更新 更多