Java 如何使用内容类型 XML 和查询参数触发 HTTP 帖子?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18272154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:56:00  来源:igfitidea点击:

How to fire HTTP post with content type XML along with query parameters?

javahttpjaxbhttp-headersxmlhttprequest

提问by Ioan

I am trying to fire a POST request. The data I am sending is XML format (I am doing this via JAXB), but I have to send along a request parameter. My problem is regarding the Content-Type(I've added some comments in the code). Which one should I use ?

我正在尝试触发 POST 请求。我发送的数据是 XML 格式(我通过 JAXB 执行此操作),但我必须发送请求参数。我的问题是关于Content-Type(我在代码中添加了一些注释)。我应该使用哪一种?

See below my code :

请参阅下面我的代码:

       private V callAndGetResponse(K request, Class<K> requestClassType, Class<V> responseClassType) throws Exception {
    JAXBContext jaxbContext = JAXBContext.newInstance(requestClassType, responseClassType);

    Marshaller marshaller = jaxbContext.createMarshaller();
    // set properties on marshaller
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
    marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", String.format(XML_HEADER_FORMAT, dtd));
    marshaller.marshal(request, System.out);

    URL wsUrl = new URL(primaryEndpointUrl);
    HttpURLConnection connection = openAndPrepareConnection(wsUrl);
    tryToMarshallWsRequestToOutputStream(request, marshaller, connection);

    printDebug(connection);

    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    Object response = unmarshaller.unmarshal(connection.getInputStream());

    // cleanup
    connection.disconnect();
    return responseClassType.cast(response);
}

private HttpURLConnection openAndPrepareConnection(URL wsUrl) throws IOException {
    HttpURLConnection connection = (HttpURLConnection) wsUrl.openConnection();
    connection.setDoOutput(true);
    connection.setRequestProperty("Accept", "application/xml");
    connection.setRequestProperty("Accept-Charset", charset);
    // Both types ? Doesn't work
    connection.setRequestProperty("Content-Type", "application/xml;application/x-www-form-urlencoded");
    // Only app/xml ? it seems that query param is not added to request
    connection.setRequestProperty("Content-Type", "application/xml");
    // Only app/query param ? it seems that xml is not added to request
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

    return connection;
}

private void tryToMarshallWsRequestToOutputStream(K request, Marshaller jaxbForRequestMarshaller,
        HttpURLConnection connection) throws JAXBException, IOException {
    OutputStream outputStream = null;
    try {
        outputStream = connection.getOutputStream();
        jaxbForRequestMarshaller.marshal(request, outputStream);
        addQueryParameters(outputStream);
    }
    finally {
        tryToClose(outputStream);
    }
}

private void addQueryParameters(OutputStream outputStream) throws IOException {
    String value = "none";
    String query = String.format("xmlmsg=%s", URLEncoder.encode(value, charset));
    outputStream.write(query.getBytes(charset));
}

protected void tryToClose(OutputStream outputStream) throws IOException {
    if (outputStream != null) {
        outputStream.close();
    }
}

Thanks a lot!

非常感谢!

采纳答案by Kylar

Ok, there's two different issues that you're dealing with:

好的,您正在处理两个不同的问题:

1) Content-Type of the body. In this case, if your body is an XML body, so it should be:

1) 正文的内容类型。在这种情况下,如果您的正文是 XML 正文,那么它应该是:

Content-Type: application/xml; charset="utf-8"

2) The fact that your query parameters are being stripped off (or ignored). This is a more complicated problem. When a form is submitted via an HTTP Post, it is often sent as query string params, and this looks like what might be happening. Can you get a wire trace of what's being sent? It may be that you'll need to parse the parameters off yourself instead of trying to parse them as a form body.

2)您的查询参数被剥离(或忽略)的事实。这是一个更复杂的问题。当表单通过 HTTP Post 提交时,它通常作为查询字符串参数发送,这看起来像是可能发生的事情。你能得到正在发送什么的线路追踪吗?您可能需要自己解析参数,而不是尝试将它们解析为表单体。

If you need to send two different types of data, you may consider sending something like a multipart form, or sending one body type, and adding extra data as a header.

如果您需要发送两种不同类型的数据,您可以考虑发送类似多部分表单的内容,或发送一种正文类型,并添加额外数据作为标头。